/*
 * Copyright (c) 2000, 2017 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

/*
 * @(#)utf8.cpp	1.3 06/26/07
 */ 

#include <stdlib.h>
#include "utf8.h"

#define LDAP_UTF8LEN(s)  ((0x80 & *(unsigned char*)(s)) ?   ldap_utf8len (s) : 1)
#define LDAP_UTF8NEXT(s) ((0x80 & *(unsigned char*)(s)) ?   ldap_utf8next(s) : (s)+1)
#define LDAP_UTF8INC(s)  ((0x80 & *(unsigned char*)(s)) ? s=ldap_utf8next(s) : ++s)

#define LDAP_UTF8PREV(s)   ldap_utf8prev(s)
#define LDAP_UTF8DEC(s) (s=ldap_utf8prev(s))

#define LDAP_UTF8COPY(d,s) ((0x80 & *(unsigned char*)(s)) ? ldap_utf8copy(d,s) : ((*(d) = *(s)), 1))
#define LDAP_UTF8GETCC(s) ((0x80 & *(unsigned char*)(s)) ? ldap_utf8getcc (&s) : *s++)
#define LDAP_UTF8GETC(s) ((0x80 & *(unsigned char*)(s)) ? ldap_utf8getcc ((const char**)&s) : *s++)

static char UTF8len[64]
= {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 6};


int
ldap_utf8len (const char* s)
  /* Return the number of char's in the character at *s. */
{
  return (int)(ldap_utf8next((char*)s) - s);
}

char*
ldap_utf8next (char* s)
  /* Return a pointer to the character immediately following *s.
     Handle any valid UTF-8 character, including '\0' and ASCII.
     Try to handle a misaligned pointer or a malformed character.
  */
{
  register unsigned char* next = (unsigned char*)s;
  switch (UTF8len [(*next >> 2) & 0x3F]) {
  case 0: /* erroneous: s points to the middle of a character. */
  case 6: if ((*++next & 0xC0) != 0x80) break;
  case 5: if ((*++next & 0xC0) != 0x80) break;
  case 4: if ((*++next & 0xC0) != 0x80) break;
  case 3: if ((*++next & 0xC0) != 0x80) break;
  case 2: if ((*++next & 0xC0) != 0x80) break;
  case 1: ++next;
  }
  return (char*) next;
}

char*
ldap_utf8prev (char* s)
  /* Return a pointer to the character immediately preceding *s.
     Handle any valid UTF-8 character, including '\0' and ASCII.
     Try to handle a misaligned pointer or a malformed character.
  */
{
  register unsigned char* prev = (unsigned char*)s;
  unsigned char* limit = prev - 6;
  while (((*--prev & 0xC0) == 0x80) && (prev != limit)) {
    ;
  }
  return (char*) prev;
}

int
ldap_utf8copy (char* dst, const char* src)
  /* Copy a character from src to dst; return the number of char's copied.
     Handle any valid UTF-8 character, including '\0' and ASCII.
     Try to handle a misaligned pointer or a malformed character.
  */
{
  register const unsigned char* s = (const unsigned char*)src;
  switch (UTF8len [(*s >> 2) & 0x3F]) {
  case 0: /* erroneous: s points to the middle of a character. */
  case 6: *dst++ = *s++; if ((*s & 0xC0) != 0x80) break;
  case 5: *dst++ = *s++; if ((*s & 0xC0) != 0x80) break;
  case 4: *dst++ = *s++; if ((*s & 0xC0) != 0x80) break;
  case 3: *dst++ = *s++; if ((*s & 0xC0) != 0x80) break;
  case 2: *dst++ = *s++; if ((*s & 0xC0) != 0x80) break;
  case 1: *dst   = *s++;
  }
  return (int)(s - (const unsigned char*)src);
}

size_t
ldap_utf8characters (const char* src)
  /* Return the number of UTF-8 characters in the 0-terminated array s. */
{
  register char* s = (char*)src;
  size_t n;
  for (n = 0; *s; LDAP_UTF8INC(s)) ++n;
  return n;
}

unsigned long 
ldap_utf8getcc( const char** src )
{
  register unsigned long c = 0;
  register const unsigned char* s = (const unsigned char*)*src;
  switch (UTF8len [(*s >> 2) & 0x3F]) {
  case 0: /* erroneous: s points to the middle of a character. */
    c = (*s++) & 0x3F; goto more5;
  case 1: c = (*s++); break;
  case 2: c = (*s++) & 0x1F; goto more1;
  case 3: c = (*s++) & 0x0F; goto more2;
  case 4: c = (*s++) & 0x07; goto more3;
  case 5: c = (*s++) & 0x03; goto more4;
  case 6: c = (*s++) & 0x01; goto more5;
  more5: if ((*s & 0xC0) != 0x80) break; c = (c << 6) | ((*s++) & 0x3F);
  more4: if ((*s & 0xC0) != 0x80) break; c = (c << 6) | ((*s++) & 0x3F);
  more3: if ((*s & 0xC0) != 0x80) break; c = (c << 6) | ((*s++) & 0x3F);
  more2: if ((*s & 0xC0) != 0x80) break; c = (c << 6) | ((*s++) & 0x3F);
  more1: if ((*s & 0xC0) != 0x80) break; c = (c << 6) | ((*s++) & 0x3F);
  break;
  }
  *src = (const char*)s;
  return c;
}

//  char*
//  ldap_utf8strtok_r( char* sp, const char* brk, char** next)
//  {
//    const char *bp;
//    unsigned long sc, bc;
//    char *tok;
  
//    if (sp == NULL && (sp = *next) == NULL)
//      return NULL;
  
//    /* Skip leading delimiters; roughly, sp += strspn(sp, brk) */
//   cont:
//    sc = LDAP_UTF8GETC(sp);
//    for (bp = brk; (bc = LDAP_UTF8GETCC(bp)) != 0;) {
//  	if (sc == bc)
//  	  goto cont;
//    }

//    if (sc == 0) { /* no non-delimiter characters */
//      *next = NULL;
//      return NULL;
//    }
//    tok = LDAP_UTF8PREV(sp);
  
//    /* Scan token; roughly, sp += strcspn(sp, brk)
//     * Note that brk must be 0-terminated; we stop if we see that, too.
//     */
//    while (1) {
//      sc = LDAP_UTF8GETC(sp);
//      bp = brk;
//      do {
//        if ((bc = LDAP_UTF8GETCC(bp)) == sc) {
//  	if (sc == 0) {
//  	  *next = NULL;
//  	} else {
//  	  *next = sp;
//  	  *(LDAP_UTF8PREV(sp)) = 0;
//  	}
//  	return tok;
//        }
//      } while (bc != 0);
//    }
//    /* NOTREACHED */
//  }

//  int
//  ldap_utf8isalnum( char* s )
//  {
//    register unsigned char c = *(unsigned char*)s;
//    if (0x80 & c) return 0;
//    if (c >= 'A' && c <= 'Z') return 1;
//    if (c >= 'a' && c <= 'z') return 1;
//    if (c >= '0' && c <= '9') return 1;
//    return 0;
//  }

//  int
//  ldap_utf8isalpha( char* s )
//  {
//    register unsigned char c = *(unsigned char*)s;
//    if (0x80 & c) return 0;
//    if (c >= 'A' && c <= 'Z') return 1;
//    if (c >= 'a' && c <= 'z') return 1;
//    return 0;
//  }

//  int
//  ldap_utf8isdigit( char* s )
//  {
//    register unsigned char c = *(unsigned char*)s;
//    if (0x80 & c) return 0;
//    if (c >= '0' && c <= '9') return 1;
//    return 0;
//  }

//  int
//  ldap_utf8isxdigit( char* s )
//  {
//    register unsigned char c = *(unsigned char*)s;
//    if (0x80 & c) return 0;
//    if (c >= '0' && c <= '9') return 1;
//    if (c >= 'A' && c <= 'F') return 1;
//    if (c >= 'a' && c <= 'f') return 1;
//    return 0;
//  }

//  int
//  ldap_utf8isspace( char* s )
//  {
//    register unsigned char *c = (unsigned char*)s;
//    int len = ldap_utf8len(s);
  
//    if (len == 0) {
//      return 0;
//      } else if (len == 1) {
//        switch (*c) {
//        case 0x09:
//        case 0x0A:
//        case 0x0B:
//        case 0x0C:
//        case 0x0D:
//        case 0x20:
//  	return 1;
//        default:
//  	return 0;
//        }
//      } else if (len == 2) {
//        if (*c == 0xc2) {
//  	return *(c+1) == 0x80;
//        }
//      } else if (len == 3) {
//        if (*c == 0xE2) {
//  	c++;
//  	if (*c == 0x80) {
//  	  c++;
//  	  return (*c>=0x80 && *c<=0x8a);
//  	}
//        } else if (*c == 0xE3) {
//  	return (*(c+1)==0x80) && (*(c+2)==0x80);
//        } else if (*c==0xEF) {
//  	return (*(c+1)==0xBB) && (*(c+2)==0xBF);
//        }
//        return 0;
//      }
  
//    /* should never reach here */
//    return 0;
//  }


//  unsigned char *ldap_UTF8STRTOLOWER(char *s);
//  void ldap_UTF8TOLOWER(char *s, char *d, int *ssz, int *dsz);
//  int ldap_UTF8ISUPPER(char *s);
//  unsigned char *ldap_UTF8STRTOUPPER(char *s);
//  void ldap_UTF8TOUPPER(char *s, char *d, int *ssz, int *dsz);
//  int ldap_UTF8ISLOWER(char *s);
//  //int ldap_UTF8CASECMP(char *s0, char *s1);
//  //int ldap_UTF8NCASECMP(char *s0, char *s1, int n);


//  typedef struct sUpperLowerTbl {
//    char const *upper, *lower;
//    int tsz;	/* target size */
//  } UpperLowerTbl_t;

//  /*
//   * ldap_has8thBit: check the input string
//   *                  return 1 if the string contains 8-bit character
//   *                  return 0 otherwise
//   */
//  int
//  ldap_has8thBit(const unsigned char *s)
//  {
//    const unsigned char *p, *tail;
//    tail = s + strlen((char *)s);
//    for (p = s; p < tail; p++) {
//      if (0x80 & *p) {
//        return 1;
//      }
//    }
//    return 0;
//  }

//  /*
//   * UpperToLower Tables: sorted by upper characters
//   */
//  UpperLowerTbl_t Upper2LowerTbl20[] = {
//      /* upper,    lower */
//      {"\303\200", "\303\240", 2},
//      {"\303\201", "\303\241", 2},
//      {"\303\202", "\303\242", 2},
//      {"\303\203", "\303\243", 2},
//      {"\303\204", "\303\244", 2},
//      {"\303\205", "\303\245", 2},
//      {"\303\206", "\303\246", 2},
//      {"\303\207", "\303\247", 2},
//      {"\303\210", "\303\250", 2},
//      {"\303\211", "\303\251", 2},
//      {"\303\212", "\303\252", 2},
//      {"\303\213", "\303\253", 2},
//      {"\303\214", "\303\254", 2},
//      {"\303\215", "\303\255", 2},
//      {"\303\216", "\303\256", 2},
//      {"\303\217", "\303\257", 2},
//      {"\303\220", "\303\260", 2},
//      {"\303\221", "\303\261", 2},
//      {"\303\222", "\303\262", 2},
//      {"\303\223", "\303\263", 2},
//      {"\303\224", "\303\264", 2},
//      {"\303\225", "\303\265", 2},
//      {"\303\226", "\303\266", 2},
//      {"\303\230", "\303\270", 2},
//      {"\303\231", "\303\271", 2},
//      {"\303\232", "\303\272", 2},
//      {"\303\233", "\303\273", 2},
//      {"\303\234", "\303\274", 2},
//      {"\303\235", "\303\275", 2},
//      {"\303\236", "\303\276", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Upper2LowerTbl21[] = {
//      {"\304\200", "\304\201", 2},
//      {"\304\202", "\304\203", 2},
//      {"\304\204", "\304\205", 2},
//      {"\304\206", "\304\207", 2},
//      {"\304\210", "\304\211", 2},
//      {"\304\212", "\304\213", 2},
//      {"\304\214", "\304\215", 2},
//      {"\304\216", "\304\217", 2},
//      {"\304\220", "\304\221", 2},
//      {"\304\222", "\304\223", 2},
//      {"\304\224", "\304\225", 2},
//      {"\304\226", "\304\227", 2},
//      {"\304\230", "\304\231", 2},
//      {"\304\232", "\304\233", 2},
//      {"\304\234", "\304\235", 2},
//      {"\304\236", "\304\237", 2},
//      {"\304\240", "\304\241", 2},
//      {"\304\242", "\304\243", 2},
//      {"\304\244", "\304\245", 2},
//      {"\304\246", "\304\247", 2},
//      {"\304\250", "\304\251", 2},
//      {"\304\252", "\304\253", 2},
//      {"\304\254", "\304\255", 2},
//      {"\304\256", "\304\257", 2},
//      {"\304\260", "\151", 1},
//      {"\304\262", "\304\263", 2},
//      {"\304\264", "\304\265", 2},
//      {"\304\266", "\304\267", 2},
//      {"\304\271", "\304\272", 2},
//      {"\304\273", "\304\274", 2},
//      {"\304\275", "\304\276", 2},
//      {"\304\277", "\305\200", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Upper2LowerTbl22[] = {
//      {"\305\201", "\305\202", 2},
//      {"\305\203", "\305\204", 2},
//      {"\305\205", "\305\206", 2},
//      {"\305\207", "\305\210", 2},
//      {"\305\212", "\305\213", 2},
//      {"\305\214", "\305\215", 2},
//      {"\305\216", "\305\217", 2},
//      {"\305\220", "\305\221", 2},
//      {"\305\222", "\305\223", 2},
//      {"\305\224", "\305\225", 2},
//      {"\305\226", "\305\227", 2},
//      {"\305\230", "\305\231", 2},
//      {"\305\232", "\305\233", 2},
//      {"\305\234", "\305\235", 2},
//      {"\305\236", "\305\237", 2},
//      {"\305\240", "\305\241", 2},
//      {"\305\242", "\305\243", 2},
//      {"\305\244", "\305\245", 2},
//      {"\305\246", "\305\247", 2},
//      {"\305\250", "\305\251", 2},
//      {"\305\252", "\305\253", 2},
//      {"\305\254", "\305\255", 2},
//      {"\305\256", "\305\257", 2},
//      {"\305\260", "\305\261", 2},
//      {"\305\262", "\305\263", 2},
//      {"\305\264", "\305\265", 2},
//      {"\305\266", "\305\267", 2},
//      {"\305\270", "\303\277", 2},
//      {"\305\271", "\305\272", 2},
//      {"\305\273", "\305\274", 2},
//      {"\305\275", "\305\276", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Upper2LowerTbl23[] = {
//      {"\306\201", "\311\223", 2},
//      {"\306\202", "\306\203", 2},
//      {"\306\204", "\306\205", 2},
//      {"\306\206", "\311\224", 2},
//      {"\306\207", "\306\210", 2},
//      {"\306\211", "\311\226", 2},
//      {"\306\212", "\311\227", 2},
//      {"\306\213", "\306\214", 2},
//      {"\306\216", "\311\230", 2},
//      {"\306\217", "\311\231", 2},
//      {"\306\220", "\311\233", 2},
//      {"\306\221", "\306\222", 2},
//      {"\306\223", "\311\240", 2},
//      {"\306\224", "\311\243", 2},
//      {"\306\226", "\311\251", 2},
//      {"\306\227", "\311\250", 2},
//      {"\306\230", "\306\231", 2},
//      {"\306\234", "\311\257", 2},
//      {"\306\235", "\311\262", 2},
//      {"\306\237", "\306\237", 2},
//      {"\306\240", "\306\241", 2},
//      {"\306\242", "\306\243", 2},
//      {"\306\244", "\306\245", 2},
//      {"\306\246", "\306\246", 2},
//      {"\306\247", "\306\250", 2},
//      {"\306\251", "\312\203", 2},
//      {"\306\254", "\306\255", 2},
//      {"\306\256", "\312\210", 2},
//      {"\306\257", "\306\260", 2},
//      {"\306\261", "\312\212", 2},
//      {"\306\262", "\312\213", 2},
//      {"\306\263", "\306\264", 2},
//      {"\306\265", "\306\266", 2},
//      {"\306\267", "\312\222", 2},
//      {"\306\270", "\306\271", 2},
//      {"\306\274", "\306\275", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Upper2LowerTbl24[] = {
//      {"\307\204", "\307\205", 2},
//      {"\307\205", "\307\204", 2},
//      {"\307\207", "\307\210", 2},
//      {"\307\210", "\307\207", 2},
//      {"\307\212", "\307\213", 2},
//      {"\307\213", "\307\212", 2},
//      {"\307\215", "\307\216", 2},
//      {"\307\217", "\307\220", 2},
//      {"\307\221", "\307\222", 2},
//      {"\307\223", "\307\224", 2},
//      {"\307\225", "\307\226", 2},
//      {"\307\227", "\307\230", 2},
//      {"\307\231", "\307\232", 2},
//      {"\307\233", "\307\234", 2},
//      {"\307\236", "\307\237", 2},
//      {"\307\240", "\307\241", 2},
//      {"\307\242", "\307\243", 2},
//      {"\307\244", "\307\245", 2},
//      {"\307\246", "\307\247", 2},
//      {"\307\250", "\307\251", 2},
//      {"\307\252", "\307\253", 2},
//      {"\307\254", "\307\255", 2},
//      {"\307\256", "\307\257", 2},
//      {"\307\261", "\307\262", 2},
//      {"\307\262", "\307\261", 2},
//      {"\307\264", "\307\265", 2},
//      {"\307\272", "\307\273", 2},
//      {"\307\274", "\307\275", 2},
//      {"\307\276", "\307\277", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Upper2LowerTbl25[] = {
//      {"\310\200", "\310\201", 2},
//      {"\310\202", "\310\203", 2},
//      {"\310\204", "\310\205", 2},
//      {"\310\206", "\310\207", 2},
//      {"\310\210", "\310\211", 2},
//      {"\310\212", "\310\213", 2},
//      {"\310\214", "\310\215", 2},
//      {"\310\216", "\310\217", 2},
//      {"\310\220", "\310\221", 2},
//      {"\310\222", "\310\223", 2},
//      {"\310\224", "\310\225", 2},
//      {"\310\226", "\310\227", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Upper2LowerTbl26[] = {
//      {"\316\206", "\316\254", 2},
//      {"\316\210", "\316\255", 2},
//      {"\316\211", "\316\256", 2},
//      {"\316\212", "\316\257", 2},
//      {"\316\214", "\317\214", 2},
//      {"\316\216", "\317\215", 2},
//      {"\316\217", "\317\216", 2},
//      {"\316\221", "\316\261", 2},
//      {"\316\222", "\316\262", 2},
//      {"\316\223", "\316\263", 2},
//      {"\316\224", "\316\264", 2},
//      {"\316\225", "\316\265", 2},
//      {"\316\226", "\316\266", 2},
//      {"\316\227", "\316\267", 2},
//      {"\316\230", "\316\270", 2},
//      {"\316\231", "\316\271", 2},
//      {"\316\232", "\316\272", 2},
//      {"\316\233", "\316\273", 2},
//      {"\316\234", "\316\274", 2},
//      {"\316\235", "\316\275", 2},
//      {"\316\236", "\316\276", 2},
//      {"\316\237", "\316\277", 2},
//      {"\316\240", "\317\200", 2},
//      {"\316\241", "\317\201", 2},
//      {"\316\243", "\317\203", 2},
//      {"\316\244", "\317\204", 2},
//      {"\316\245", "\317\205", 2},
//      {"\316\246", "\317\206", 2},
//      {"\316\247", "\317\207", 2},
//      {"\316\250", "\317\210", 2},
//      {"\316\251", "\317\211", 2},
//      {"\316\252", "\317\212", 2},
//      {"\316\253", "\317\213", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Upper2LowerTbl27[] = {
//      {"\317\222", "\317\222", 2},
//      {"\317\223", "\317\223", 2},
//      {"\317\224", "\317\224", 2},
//      {"\317\232", "\317\232", 2},
//      {"\317\234", "\317\234", 2},
//      {"\317\236", "\317\236", 2},
//      {"\317\240", "\317\240", 2},
//      {"\317\242", "\317\243", 2},
//      {"\317\244", "\317\245", 2},
//      {"\317\246", "\317\247", 2},
//      {"\317\250", "\317\251", 2},
//      {"\317\252", "\317\253", 2},
//      {"\317\254", "\317\255", 2},
//      {"\317\256", "\317\257", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Upper2LowerTbl28[] = {
//      {"\320\201", "\321\221", 2},
//      {"\320\202", "\321\222", 2},
//      {"\320\203", "\321\223", 2},
//      {"\320\204", "\321\224", 2},
//      {"\320\205", "\321\225", 2},
//      {"\320\206", "\321\226", 2},
//      {"\320\207", "\321\227", 2},
//      {"\320\210", "\321\230", 2},
//      {"\320\211", "\321\231", 2},
//      {"\320\212", "\321\232", 2},
//      {"\320\213", "\321\233", 2},
//      {"\320\214", "\321\234", 2},
//      {"\320\216", "\321\236", 2},
//      {"\320\217", "\321\237", 2},
//      {"\320\220", "\320\260", 2},
//      {"\320\221", "\320\261", 2},
//      {"\320\222", "\320\262", 2},
//      {"\320\223", "\320\263", 2},
//      {"\320\224", "\320\264", 2},
//      {"\320\225", "\320\265", 2},
//      {"\320\226", "\320\266", 2},
//      {"\320\227", "\320\267", 2},
//      {"\320\230", "\320\270", 2},
//      {"\320\231", "\320\271", 2},
//      {"\320\232", "\320\272", 2},
//      {"\320\233", "\320\273", 2},
//      {"\320\234", "\320\274", 2},
//      {"\320\235", "\320\275", 2},
//      {"\320\236", "\320\276", 2},
//      {"\320\237", "\320\277", 2},
//      {"\320\240", "\321\200", 2},
//      {"\320\241", "\321\201", 2},
//      {"\320\242", "\321\202", 2},
//      {"\320\243", "\321\203", 2},
//      {"\320\244", "\321\204", 2},
//      {"\320\245", "\321\205", 2},
//      {"\320\246", "\321\206", 2},
//      {"\320\247", "\321\207", 2},
//      {"\320\250", "\321\210", 2},
//      {"\320\251", "\321\211", 2},
//      {"\320\252", "\321\212", 2},
//      {"\320\253", "\321\213", 2},
//      {"\320\254", "\321\214", 2},
//      {"\320\255", "\321\215", 2},
//      {"\320\256", "\321\216", 2},
//      {"\320\257", "\321\217", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Upper2LowerTbl29[] = {
//      {"\321\240", "\321\241", 2},
//      {"\321\242", "\321\243", 2},
//      {"\321\244", "\321\245", 2},
//      {"\321\246", "\321\247", 2},
//      {"\321\250", "\321\251", 2},
//      {"\321\252", "\321\253", 2},
//      {"\321\254", "\321\255", 2},
//      {"\321\256", "\321\257", 2},
//      {"\321\260", "\321\261", 2},
//      {"\321\262", "\321\263", 2},
//      {"\321\264", "\321\265", 2},
//      {"\321\266", "\321\267", 2},
//      {"\321\270", "\321\271", 2},
//      {"\321\272", "\321\273", 2},
//      {"\321\274", "\321\275", 2},
//      {"\321\276", "\321\277", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Upper2LowerTbl2a[] = {
//      {"\322\200", "\322\201", 2},
//      {"\322\220", "\322\221", 2},
//      {"\322\222", "\322\223", 2},
//      {"\322\224", "\322\225", 2},
//      {"\322\226", "\322\227", 2},
//      {"\322\230", "\322\231", 2},
//      {"\322\232", "\322\233", 2},
//      {"\322\234", "\322\235", 2},
//      {"\322\236", "\322\237", 2},
//      {"\322\240", "\322\241", 2},
//      {"\322\242", "\322\243", 2},
//      {"\322\244", "\322\245", 2},
//      {"\322\246", "\322\247", 2},
//      {"\322\250", "\322\251", 2},
//      {"\322\252", "\322\253", 2},
//      {"\322\254", "\322\255", 2},
//      {"\322\256", "\322\257", 2},
//      {"\322\260", "\322\261", 2},
//      {"\322\262", "\322\263", 2},
//      {"\322\264", "\322\265", 2},
//      {"\322\266", "\322\267", 2},
//      {"\322\270", "\322\271", 2},
//      {"\322\272", "\322\273", 2},
//      {"\322\274", "\322\275", 2},
//      {"\322\276", "\322\277", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Upper2LowerTbl2b[] = {
//      {"\323\201", "\323\202", 2},
//      {"\323\203", "\323\204", 2},
//      {"\323\207", "\323\210", 2},
//      {"\323\213", "\323\214", 2},
//      {"\323\220", "\323\221", 2},
//      {"\323\222", "\323\223", 2},
//      {"\323\224", "\323\225", 2},
//      {"\323\226", "\323\227", 2},
//      {"\323\230", "\323\231", 2},
//      {"\323\232", "\323\233", 2},
//      {"\323\234", "\323\235", 2},
//      {"\323\236", "\323\237", 2},
//      {"\323\240", "\323\241", 2},
//      {"\323\242", "\323\243", 2},
//      {"\323\244", "\323\245", 2},
//      {"\323\246", "\323\247", 2},
//      {"\323\250", "\323\251", 2},
//      {"\323\252", "\323\253", 2},
//      {"\323\256", "\323\257", 2},
//      {"\323\260", "\323\261", 2},
//      {"\323\262", "\323\263", 2},
//      {"\323\264", "\323\265", 2},
//      {"\323\270", "\323\271", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Upper2LowerTbl2c[] = {
//      {"\324\261", "\325\241", 2},
//      {"\324\262", "\325\242", 2},
//      {"\324\263", "\325\243", 2},
//      {"\324\264", "\325\244", 2},
//      {"\324\265", "\325\245", 2},
//      {"\324\266", "\325\246", 2},
//      {"\324\267", "\325\247", 2},
//      {"\324\270", "\325\250", 2},
//      {"\324\271", "\325\251", 2},
//      {"\324\272", "\325\252", 2},
//      {"\324\273", "\325\253", 2},
//      {"\324\274", "\325\254", 2},
//      {"\324\275", "\325\255", 2},
//      {"\324\276", "\325\256", 2},
//      {"\324\277", "\325\257", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Upper2LowerTbl2d[] = {
//      {"\325\200", "\325\260", 2},
//      {"\325\201", "\325\261", 2},
//      {"\325\202", "\325\262", 2},
//      {"\325\203", "\325\263", 2},
//      {"\325\204", "\325\264", 2},
//      {"\325\205", "\325\265", 2},
//      {"\325\206", "\325\266", 2},
//      {"\325\207", "\325\267", 2},
//      {"\325\210", "\325\270", 2},
//      {"\325\211", "\325\271", 2},
//      {"\325\212", "\325\272", 2},
//      {"\325\213", "\325\273", 2},
//      {"\325\214", "\325\274", 2},
//      {"\325\215", "\325\275", 2},
//      {"\325\216", "\325\276", 2},
//      {"\325\217", "\325\277", 2},
//      {"\325\220", "\326\200", 2},
//      {"\325\221", "\326\201", 2},
//      {"\325\222", "\326\202", 2},
//      {"\325\223", "\326\203", 2},
//      {"\325\224", "\326\204", 2},
//      {"\325\225", "\326\205", 2},
//      {"\325\226", "\326\206", 2},
//      {NULL, NULL, 0}
//      /* upper,        lower */
//  };

//  UpperLowerTbl_t Upper2LowerTbl30[] = {
//      /* upper,        lower */
//      {"\341\202\240", "\341\203\220", 3},
//      {"\341\202\241", "\341\203\221", 3},
//      {"\341\202\242", "\341\203\222", 3},
//      {"\341\202\243", "\341\203\223", 3},
//      {"\341\202\244", "\341\203\224", 3},
//      {"\341\202\245", "\341\203\225", 3},
//      {"\341\202\246", "\341\203\226", 3},
//      {"\341\202\247", "\341\203\227", 3},
//      {"\341\202\250", "\341\203\230", 3},
//      {"\341\202\251", "\341\203\231", 3},
//      {"\341\202\252", "\341\203\232", 3},
//      {"\341\202\253", "\341\203\233", 3},
//      {"\341\202\254", "\341\203\234", 3},
//      {"\341\202\255", "\341\203\235", 3},
//      {"\341\202\256", "\341\203\236", 3},
//      {"\341\202\257", "\341\203\237", 3},
//      {"\341\202\260", "\341\203\240", 3},
//      {"\341\202\261", "\341\203\241", 3},
//      {"\341\202\262", "\341\203\242", 3},
//      {"\341\202\263", "\341\203\243", 3},
//      {"\341\202\264", "\341\203\244", 3},
//      {"\341\202\265", "\341\203\245", 3},
//      {"\341\202\266", "\341\203\246", 3},
//      {"\341\202\267", "\341\203\247", 3},
//      {"\341\202\270", "\341\203\250", 3},
//      {"\341\202\271", "\341\203\251", 3},
//      {"\341\202\272", "\341\203\252", 3},
//      {"\341\202\273", "\341\203\253", 3},
//      {"\341\202\274", "\341\203\254", 3},
//      {"\341\202\275", "\341\203\255", 3},
//      {"\341\202\276", "\341\203\256", 3},
//      {"\341\202\277", "\341\203\257", 3},
//      {"\341\203\200", "\341\203\260", 3},
//      {"\341\203\201", "\341\203\261", 3},
//      {"\341\203\202", "\341\203\262", 3},
//      {"\341\203\203", "\341\203\263", 3},
//      {"\341\203\204", "\341\203\264", 3},
//      {"\341\203\205", "\341\203\265", 3},
//      {"\341\270\200", "\341\270\201", 3},
//      {"\341\270\202", "\341\270\203", 3},
//      {"\341\270\204", "\341\270\205", 3},
//      {"\341\270\206", "\341\270\207", 3},
//      {"\341\270\210", "\341\270\211", 3},
//      {"\341\270\212", "\341\270\213", 3},
//      {"\341\270\214", "\341\270\215", 3},
//      {"\341\270\216", "\341\270\217", 3},
//      {"\341\270\220", "\341\270\221", 3},
//      {"\341\270\222", "\341\270\223", 3},
//      {"\341\270\224", "\341\270\225", 3},
//      {"\341\270\226", "\341\270\227", 3},
//      {"\341\270\230", "\341\270\231", 3},
//      {"\341\270\232", "\341\270\233", 3},
//      {"\341\270\234", "\341\270\235", 3},
//      {"\341\270\236", "\341\270\237", 3},
//      {"\341\270\240", "\341\270\241", 3},
//      {"\341\270\242", "\341\270\243", 3},
//      {"\341\270\244", "\341\270\245", 3},
//      {"\341\270\246", "\341\270\247", 3},
//      {"\341\270\250", "\341\270\251", 3},
//      {"\341\270\252", "\341\270\253", 3},
//      {"\341\270\254", "\341\270\255", 3},
//      {"\341\270\256", "\341\270\257", 3},
//      {"\341\270\260", "\341\270\261", 3},
//      {"\341\270\262", "\341\270\263", 3},
//      {"\341\270\264", "\341\270\265", 3},
//      {"\341\270\266", "\341\270\267", 3},
//      {"\341\270\270", "\341\270\271", 3},
//      {"\341\270\272", "\341\270\273", 3},
//      {"\341\270\274", "\341\270\275", 3},
//      {"\341\270\276", "\341\270\277", 3},
//      {"\341\271\200", "\341\271\201", 3},
//      {"\341\271\202", "\341\271\203", 3},
//      {"\341\271\204", "\341\271\205", 3},
//      {"\341\271\206", "\341\271\207", 3},
//      {"\341\271\210", "\341\271\211", 3},
//      {"\341\271\212", "\341\271\213", 3},
//      {"\341\271\214", "\341\271\215", 3},
//      {"\341\271\216", "\341\271\217", 3},
//      {"\341\271\220", "\341\271\221", 3},
//      {"\341\271\222", "\341\271\223", 3},
//      {"\341\271\224", "\341\271\225", 3},
//      {"\341\271\226", "\341\271\227", 3},
//      {"\341\271\230", "\341\271\231", 3},
//      {"\341\271\232", "\341\271\233", 3},
//      {"\341\271\234", "\341\271\235", 3},
//      {"\341\271\236", "\341\271\237", 3},
//      {"\341\271\240", "\341\271\241", 3},
//      {"\341\271\242", "\341\271\243", 3},
//      {"\341\271\244", "\341\271\245", 3},
//      {"\341\271\246", "\341\271\247", 3},
//      {"\341\271\250", "\341\271\251", 3},
//      {"\341\271\252", "\341\271\253", 3},
//      {"\341\271\254", "\341\271\255", 3},
//      {"\341\271\256", "\341\271\257", 3},
//      {"\341\271\260", "\341\271\261", 3},
//      {"\341\271\262", "\341\271\263", 3},
//      {"\341\271\264", "\341\271\265", 3},
//      {"\341\271\266", "\341\271\267", 3},
//      {"\341\271\270", "\341\271\271", 3},
//      {"\341\271\272", "\341\271\273", 3},
//      {"\341\271\274", "\341\271\275", 3},
//      {"\341\271\276", "\341\271\277", 3},
//      {"\341\272\200", "\341\272\201", 3},
//      {"\341\272\202", "\341\272\203", 3},
//      {"\341\272\204", "\341\272\205", 3},
//      {"\341\272\206", "\341\272\207", 3},
//      {"\341\272\210", "\341\272\211", 3},
//      {"\341\272\212", "\341\272\213", 3},
//      {"\341\272\214", "\341\272\215", 3},
//      {"\341\272\216", "\341\272\217", 3},
//      {"\341\272\220", "\341\272\221", 3},
//      {"\341\272\222", "\341\272\223", 3},
//      {"\341\272\224", "\341\272\225", 3},
//      {"\341\272\240", "\341\272\241", 3},
//      {"\341\272\242", "\341\272\243", 3},
//      {"\341\272\244", "\341\272\245", 3},
//      {"\341\272\246", "\341\272\247", 3},
//      {"\341\272\250", "\341\272\251", 3},
//      {"\341\272\252", "\341\272\253", 3},
//      {"\341\272\254", "\341\272\255", 3},
//      {"\341\272\256", "\341\272\257", 3},
//      {"\341\272\260", "\341\272\261", 3},
//      {"\341\272\262", "\341\272\263", 3},
//      {"\341\272\264", "\341\272\265", 3},
//      {"\341\272\266", "\341\272\267", 3},
//      {"\341\272\270", "\341\272\271", 3},
//      {"\341\272\272", "\341\272\273", 3},
//      {"\341\272\274", "\341\272\275", 3},
//      {"\341\272\276", "\341\272\277", 3},
//      {"\341\273\200", "\341\273\201", 3},
//      {"\341\273\202", "\341\273\203", 3},
//      {"\341\273\204", "\341\273\205", 3},
//      {"\341\273\206", "\341\273\207", 3},
//      {"\341\273\210", "\341\273\211", 3},
//      {"\341\273\212", "\341\273\213", 3},
//      {"\341\273\214", "\341\273\215", 3},
//      {"\341\273\216", "\341\273\217", 3},
//      {"\341\273\220", "\341\273\221", 3},
//      {"\341\273\222", "\341\273\223", 3},
//      {"\341\273\224", "\341\273\225", 3},
//      {"\341\273\226", "\341\273\227", 3},
//      {"\341\273\230", "\341\273\231", 3},
//      {"\341\273\232", "\341\273\233", 3},
//      {"\341\273\234", "\341\273\235", 3},
//      {"\341\273\236", "\341\273\237", 3},
//      {"\341\273\240", "\341\273\241", 3},
//      {"\341\273\242", "\341\273\243", 3},
//      {"\341\273\244", "\341\273\245", 3},
//      {"\341\273\246", "\341\273\247", 3},
//      {"\341\273\250", "\341\273\251", 3},
//      {"\341\273\252", "\341\273\253", 3},
//      {"\341\273\254", "\341\273\255", 3},
//      {"\341\273\256", "\341\273\257", 3},
//      {"\341\273\260", "\341\273\261", 3},
//      {"\341\273\262", "\341\273\263", 3},
//      {"\341\273\264", "\341\273\265", 3},
//      {"\341\273\266", "\341\273\267", 3},
//      {"\341\273\270", "\341\273\271", 3},
//      {"\341\274\210", "\341\274\200", 3},
//      {"\341\274\211", "\341\274\201", 3},
//      {"\341\274\212", "\341\274\202", 3},
//      {"\341\274\213", "\341\274\203", 3},
//      {"\341\274\214", "\341\274\204", 3},
//      {"\341\274\215", "\341\274\205", 3},
//      {"\341\274\216", "\341\274\206", 3},
//      {"\341\274\217", "\341\274\207", 3},
//      {"\341\274\230", "\341\274\220", 3},
//      {"\341\274\231", "\341\274\221", 3},
//      {"\341\274\232", "\341\274\222", 3},
//      {"\341\274\233", "\341\274\223", 3},
//      {"\341\274\234", "\341\274\224", 3},
//      {"\341\274\235", "\341\274\225", 3},
//      {"\341\274\250", "\341\274\240", 3},
//      {"\341\274\251", "\341\274\241", 3},
//      {"\341\274\252", "\341\274\242", 3},
//      {"\341\274\253", "\341\274\243", 3},
//      {"\341\274\254", "\341\274\244", 3},
//      {"\341\274\255", "\341\274\245", 3},
//      {"\341\274\256", "\341\274\246", 3},
//      {"\341\274\257", "\341\274\247", 3},
//      {"\341\274\270", "\341\274\260", 3},
//      {"\341\274\271", "\341\274\261", 3},
//      {"\341\274\272", "\341\274\262", 3},
//      {"\341\274\273", "\341\274\263", 3},
//      {"\341\274\274", "\341\274\264", 3},
//      {"\341\274\275", "\341\274\265", 3},
//      {"\341\274\276", "\341\274\266", 3},
//      {"\341\274\277", "\341\274\267", 3},
//      {"\341\275\210", "\341\275\200", 3},
//      {"\341\275\211", "\341\275\201", 3},
//      {"\341\275\212", "\341\275\202", 3},
//      {"\341\275\213", "\341\275\203", 3},
//      {"\341\275\214", "\341\275\204", 3},
//      {"\341\275\215", "\341\275\205", 3},
//      {"\341\275\231", "\341\275\221", 3},
//      {"\341\275\233", "\341\275\223", 3},
//      {"\341\275\235", "\341\275\225", 3},
//      {"\341\275\237", "\341\275\227", 3},
//      {"\341\275\250", "\341\275\240", 3},
//      {"\341\275\251", "\341\275\241", 3},
//      {"\341\275\252", "\341\275\242", 3},
//      {"\341\275\253", "\341\275\243", 3},
//      {"\341\275\254", "\341\275\244", 3},
//      {"\341\275\255", "\341\275\245", 3},
//      {"\341\275\256", "\341\275\246", 3},
//      {"\341\275\257", "\341\275\247", 3},
//      {"\341\276\210", "\341\276\200", 3},
//      {"\341\276\211", "\341\276\201", 3},
//      {"\341\276\212", "\341\276\202", 3},
//      {"\341\276\213", "\341\276\203", 3},
//      {"\341\276\214", "\341\276\204", 3},
//      {"\341\276\215", "\341\276\205", 3},
//      {"\341\276\216", "\341\276\206", 3},
//      {"\341\276\217", "\341\276\207", 3},
//      {"\341\276\230", "\341\276\220", 3},
//      {"\341\276\231", "\341\276\221", 3},
//      {"\341\276\232", "\341\276\222", 3},
//      {"\341\276\233", "\341\276\223", 3},
//      {"\341\276\234", "\341\276\224", 3},
//      {"\341\276\235", "\341\276\225", 3},
//      {"\341\276\236", "\341\276\226", 3},
//      {"\341\276\237", "\341\276\227", 3},
//      {"\341\276\250", "\341\276\240", 3},
//      {"\341\276\251", "\341\276\241", 3},
//      {"\341\276\252", "\341\276\242", 3},
//      {"\341\276\253", "\341\276\243", 3},
//      {"\341\276\254", "\341\276\244", 3},
//      {"\341\276\255", "\341\276\245", 3},
//      {"\341\276\256", "\341\276\246", 3},
//      {"\341\276\257", "\341\276\247", 3},
//      {"\341\276\270", "\341\276\260", 3},
//      {"\341\276\271", "\341\276\261", 3},
//      {"\341\276\272", "\341\275\260", 3},
//      {"\341\276\273", "\341\275\261", 3},
//      {"\341\276\274", "\341\276\263", 3},
//      {"\341\276\276", "\341\276\276", 3},
//      {"\341\277\210", "\341\275\262", 3},
//      {"\341\277\211", "\341\275\263", 3},
//      {"\341\277\212", "\341\275\264", 3},
//      {"\341\277\213", "\341\275\265", 3},
//      {"\341\277\214", "\341\277\203", 3},
//      {"\341\277\230", "\341\277\220", 3},
//      {"\341\277\231", "\341\277\221", 3},
//      {"\341\277\232", "\341\275\266", 3},
//      {"\341\277\233", "\341\275\267", 3},
//      {"\341\277\250", "\341\277\240", 3},
//      {"\341\277\251", "\341\277\241", 3},
//      {"\341\277\252", "\341\275\272", 3},
//      {"\341\277\253", "\341\275\273", 3},
//      {"\341\277\254", "\341\277\245", 3},
//      {"\341\277\270", "\341\275\270", 3},
//      {"\341\277\271", "\341\275\271", 3},
//      {"\341\277\272", "\341\275\274", 3},
//      {"\341\277\273", "\341\275\275", 3},
//      {"\341\277\274", "\341\277\263", 3},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Upper2LowerTbl31[] = {
//      {"\357\274\241", "\357\275\201", 3},
//      {"\357\274\242", "\357\275\202", 3},
//      {"\357\274\243", "\357\275\203", 3},
//      {"\357\274\244", "\357\275\204", 3},
//      {"\357\274\245", "\357\275\205", 3},
//      {"\357\274\246", "\357\275\206", 3},
//      {"\357\274\247", "\357\275\207", 3},
//      {"\357\274\250", "\357\275\210", 3},
//      {"\357\274\251", "\357\275\211", 3},
//      {"\357\274\252", "\357\275\212", 3},
//      {"\357\274\253", "\357\275\213", 3},
//      {"\357\274\254", "\357\275\214", 3},
//      {"\357\274\255", "\357\275\215", 3},
//      {"\357\274\256", "\357\275\216", 3},
//      {"\357\274\257", "\357\275\217", 3},
//      {"\357\274\260", "\357\275\220", 3},
//      {"\357\274\261", "\357\275\221", 3},
//      {"\357\274\262", "\357\275\222", 3},
//      {"\357\274\263", "\357\275\223", 3},
//      {"\357\274\264", "\357\275\224", 3},
//      {"\357\274\265", "\357\275\225", 3},
//      {"\357\274\266", "\357\275\226", 3},
//      {"\357\274\267", "\357\275\227", 3},
//      {"\357\274\270", "\357\275\230", 3},
//      {"\357\274\271", "\357\275\231", 3},
//      {"\357\274\272", "\357\275\232", 3},
//      {NULL, NULL, 0}
//      /* upper,        lower */
//  };

//  UpperLowerTbl_t *Upper2LowerTbl2[] = {
//      Upper2LowerTbl20,	/* \303 */
//      Upper2LowerTbl21,	/* \304 */
//      Upper2LowerTbl22,	/* \305 */
//      Upper2LowerTbl23,	/* \306 */
//      Upper2LowerTbl24,	/* \307 */
//      Upper2LowerTbl25,	/* \310 */
//      NULL,		/* \311 */
//      NULL,		/* \312 */
//      NULL,		/* \313 */
//      NULL,		/* \314 */
//      NULL,		/* \315 */
//      Upper2LowerTbl26,	/* \316 */
//      Upper2LowerTbl27,	/* \317 */
//      Upper2LowerTbl28,	/* \320 */
//      Upper2LowerTbl29,	/* \321 */
//      Upper2LowerTbl2a,	/* \322 */
//      Upper2LowerTbl2b,	/* \323 */
//      Upper2LowerTbl2c,	/* \324 */
//      Upper2LowerTbl2d	/* \325 */
//  };

//  UpperLowerTbl_t *Upper2LowerTbl3[] = {
//      Upper2LowerTbl30,	/* \341 */
//      NULL,		/* \342 */
//      NULL,		/* \343 */
//      NULL,		/* \344 */
//      NULL,		/* \345 */
//      NULL,		/* \346 */
//      NULL,		/* \347 */
//      NULL,		/* \350 */
//      NULL,		/* \351 */
//      NULL,		/* \352 */
//      NULL,		/* \353 */
//      NULL,		/* \354 */
//      NULL,		/* \355 */
//      NULL,		/* \356 */
//      Upper2LowerTbl31	/* \357 */
//  };

//  #define UL2S (unsigned char)'\303'
//  #define UL2E (unsigned char)'\325'
//  #define UL3S (unsigned char)'\341'
//  #define UL3E (unsigned char)'\357'

//  /*
//   * ldap_utf8StrToLower: translate upper-case string to lower-case
//   * 
//   *                input: a null terminated UTF-8 string
//   *               output: a null terminated UTF-8 string which characters are
//   *                       converted to lower-case; characters which are not
//   *                       upper-case are copied as is.  If it's not considered
//   *                       a UTF-8 string, NULL is returned.
//   *                   
//   * Notes: This function takes a string (made of multiple UTF-8 characters)
//   *        for the input (not one character as in "tolower").
//   *        Output string is allocated in this function, which needs to be
//   *        released when it's not needed any more.
//   */
//  unsigned char *
//  ldap_UTF8STRTOLOWER(char *s)
//  {
//      return ldap_utf8StrToLower((unsigned char *)s);
//  }

//  unsigned char *
//  ldap_utf8StrToLower(const unsigned char *s)
//  {
//    UpperLowerTbl_t *ultp;
//    const unsigned char *p, *np, *tail;
//    unsigned char *lp, *lphead;
//    int len, sz;
  
//    if (s == NULL || *s == '\0') {
//      return (unsigned char*)s;
//    }
//    len = strlen((char *)s);
//    tail = s + len;
//    lphead = lp = (unsigned char *)malloc(len + 1);
//    p = s;
//    while ((np = (unsigned char *)ldap_utf8next((char *)p)) <= tail) {
//      switch(sz = np - p) {
//      case 1:
//        sprintf((char *)lp, "%c", tolower(*p));
//        break;
//      case 2:
//        if (*p < UL2S || *p > UL2E) {	/* out of range */
//  	memcpy(lp, p, sz);
//  	break;
//        }
//        for (ultp = Upper2LowerTbl2[*p - UL2S];
//  	   ultp && ultp->upper && memcmp(p, ultp->upper, sz);
//  	   ultp++)
//  	;
//        if (!ultp) {		/* out of range */
//  	memcpy(lp, p, sz);
//        } else if (ultp->upper) {        /* matched */
//  	memcpy(lp, ultp->lower, ultp->tsz);
//  	sz = ultp->tsz;
//        } else {
//  	memcpy(lp, p, sz);
//        }
//        break;
//      case 3:
//        if (*p != UL3S && *p != UL3E) {	/* out of range */
//  	memcpy(lp, p, sz);
//  	break;
//        }
//        for (ultp = Upper2LowerTbl3[*p - UL3S];
//  	   ultp && ultp->upper && memcmp(p, ultp->upper, sz);
//  	   ultp++)
//  	;
//        if (!ultp) {		/* out of range */
//  	memcpy(lp, p, sz);
//        } else if (ultp->upper) {        /* matched */
//  	memcpy(lp, ultp->lower, sz);
//        } else {
//  	memcpy(lp, p, sz);
//        }
//        break;
//      case 4:
//        memcpy(lp, p, sz);
//        break;
//      default:    /* not UTF-8 */
//        free((void *)lphead);
//        return NULL;
//      }
//      lp += sz;
//      p = np;
//      if (p == tail) {
//        break;
//      }
//    }
//    *lp = '\0';
//    return lphead;
//  }

//  /*
//   * ldap_utf8ToLower: translate upper-case character to lower-case
//   * 
//   *             input: a UTF-8 character (s)
//   *            output: a UTF-8 character which is converted to lower-case (d)
//   *                    length (in bytes) of input character (ssz) and
//   *                    output character (dsz)
//   *                   
//   * Notes: This function takes a UTF-8 character (could be multiple bytes)
//   *        for the input.  Memory for the output character is NOT allocated
//   *        in this function, caller should have allocated it (d).
//   *        "memmove" is used since (s) and (d) are overlapped.
//   */
//  void
//  ldap_UTF8TOLOWER(char *s, char *d, int *ssz, int *dsz)
//  {
//    ldap_utf8ToLower((unsigned char *)s, (unsigned char *)d, ssz, dsz);
//    return;
//  }

//  void
//  ldap_utf8ToLower(unsigned char *s, unsigned char *d, int *ssz, int *dsz)
//  {
//    UpperLowerTbl_t *ultp;
//    unsigned char *tail;
  
//    if (s == NULL || *s == '\0') {
//      *ssz = *dsz = 0;
//      return;
//    }
//    if (!(*s & 0x80)) {	/* ASCII */
//      *dsz = *ssz = 1;
//      *d = tolower(*s);
//          return;
//    }
//    tail = (unsigned char *)ldap_utf8next((char *)s);
//    *dsz = *ssz = tail - s;
//    switch(*ssz) {
//    case 1:	/* ASCII */
//      *d = tolower(*s);
//      break;
//    case 2:	/* 2 bytes */
//      if (*s < UL2S || *s > UL2E) {	/* out of range */
//        memmove(d, s, *ssz);
//        break;
//      }
//      for (ultp = Upper2LowerTbl2[*s - UL2S];
//  	 ultp && ultp->upper && memcmp(s, ultp->upper, *ssz);
//  	 ultp++)
//        ;
//      if (!ultp) {			/* out of range */
//        memmove(d, s, *ssz);
//      } else if (ultp->upper) {	/* matched */
//        memmove(d, ultp->lower, ultp->tsz);
//        *dsz = ultp->tsz;
//      } else {
//        memmove(d, s, *ssz);
//      }
//      break;
//    case 3:	/* 3 bytes */
//      if (*s != UL3S && *s != UL3E) {	/* out of range */
//        memmove(d, s, *ssz);
//        break;
//      }
//      for (ultp = Upper2LowerTbl3[*s - UL3S];
//  	 ultp && ultp->upper && memcmp(s, ultp->upper, *ssz);
//  	 ultp++)
//        ;
//      if (!ultp) {	 		/* out of range */
//        memmove(d, s, *ssz);
//      } else if (ultp->upper) {       /* matched */
//        memmove(d, ultp->lower, *ssz);
//      } else {
//        memmove(d, s, *ssz);
//      }
//      break;
//    }
//    return;
//  }

//  /*
//   * ldap_utf8isUpper: tests for a character that is a upper-case letter in
//   *                   UTF-8
//   * 
//   *            input: a UTF-8 character (could be multi-byte)
//   *           output: 1 if the character is a upper-case letter
//   *                   0 if the character is not a upper-case letter
//   */
//  int
//  ldap_UTF8ISUPPER(char *s)
//  {
//    return ldap_utf8isUpper((unsigned char *)s);
//  }

//  int
//  ldap_utf8isUpper(unsigned char *s)
//  {
//    UpperLowerTbl_t *ultp;
//    unsigned char *next;
//    int sz;
  
//    if (s == NULL || *s == '\0') {
//      return 0;
//    }
//    if (!(*s & 0x80)) {	/* ASCII */
//      return isupper(*s);
//    }
//    next = (unsigned char *)ldap_utf8next((char *)s);
//    switch(sz = next - s) {
//      case 1:	/* ASCII */
//        return isupper(*s);
//    case 2:
//      if (*s < UL2S || *s > UL2E) {	/* out of range */
//        return 0;
//      }
//      for (ultp = Upper2LowerTbl2[*s - UL2S];
//  	 ultp && ultp->upper && memcmp(s, ultp->upper, sz);
//  	 ultp++)
//        ;
//      if (!ultp) {			/* out of range */
//        return 0;
//      } else if (ultp->upper) {		/* matched */
//        return 1;
//      } else {
//        return 0;
//      }
//    case 3:
//      if (*s < UL3S || *s > UL3E) {	/* out of range */
//        return 0;
//      }
//      for (ultp = Upper2LowerTbl3[*s - UL3S];
//  	 ultp && ultp->upper && memcmp(s, ultp->upper, sz);
//  	 ultp++)
//        ;
//      if (!ultp) {			/* out of range */
//        return 0;
//      } else if (ultp->upper) {		/* matched */
//        return 1;
//      } else {
//        return 0;
//          }
//    default:
//      return 0;
//    }
//  }

//  /*
//   * Lower2Upper Tables: sorted by lower characters
//   */
//  UpperLowerTbl_t Lower2UpperTbl20[] = {
//      /* upper,    lower */
//      {"\303\200", "\303\240", 2},
//      {"\303\201", "\303\241", 2},
//      {"\303\202", "\303\242", 2},
//      {"\303\203", "\303\243", 2},
//      {"\303\204", "\303\244", 2},
//      {"\303\205", "\303\245", 2},
//      {"\303\206", "\303\246", 2},
//      {"\303\207", "\303\247", 2},
//      {"\303\210", "\303\250", 2},
//      {"\303\211", "\303\251", 2},
//      {"\303\212", "\303\252", 2},
//      {"\303\213", "\303\253", 2},
//      {"\303\214", "\303\254", 2},
//      {"\303\215", "\303\255", 2},
//      {"\303\216", "\303\256", 2},
//      {"\303\217", "\303\257", 2},
//      {"\303\220", "\303\260", 2},
//      {"\303\221", "\303\261", 2},
//      {"\303\222", "\303\262", 2},
//      {"\303\223", "\303\263", 2},
//      {"\303\224", "\303\264", 2},
//      {"\303\225", "\303\265", 2},
//      {"\303\226", "\303\266", 2},
//      {"\303\230", "\303\270", 2},
//      {"\303\231", "\303\271", 2},
//      {"\303\232", "\303\272", 2},
//      {"\303\233", "\303\273", 2},
//      {"\303\234", "\303\274", 2},
//      {"\303\235", "\303\275", 2},
//      {"\303\236", "\303\276", 2},
//      {"\305\270", "\303\277", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Lower2UpperTbl21[] = {
//      {"\304\200", "\304\201", 2},
//      {"\304\202", "\304\203", 2},
//      {"\304\204", "\304\205", 2},
//      {"\304\206", "\304\207", 2},
//      {"\304\210", "\304\211", 2},
//      {"\304\212", "\304\213", 2},
//      {"\304\214", "\304\215", 2},
//      {"\304\216", "\304\217", 2},
//      {"\304\220", "\304\221", 2},
//      {"\304\222", "\304\223", 2},
//      {"\304\224", "\304\225", 2},
//      {"\304\226", "\304\227", 2},
//      {"\304\230", "\304\231", 2},
//      {"\304\232", "\304\233", 2},
//      {"\304\234", "\304\235", 2},
//      {"\304\236", "\304\237", 2},
//      {"\304\240", "\304\241", 2},
//      {"\304\242", "\304\243", 2},
//      {"\304\244", "\304\245", 2},
//      {"\304\246", "\304\247", 2},
//      {"\304\250", "\304\251", 2},
//      {"\304\252", "\304\253", 2},
//      {"\304\254", "\304\255", 2},
//      {"\304\256", "\304\257", 2},
//      {"\111", "\304\261", 1},
//      {"\304\262", "\304\263", 2},
//      {"\304\264", "\304\265", 2},
//      {"\304\266", "\304\267", 2},
//      {"\304\271", "\304\272", 2},
//      {"\304\273", "\304\274", 2},
//      {"\304\275", "\304\276", 2},
//      {NULL, NULL}
//  };

//  UpperLowerTbl_t Lower2UpperTbl22[] = {
//      {"\304\277", "\305\200", 2},
//      {"\305\201", "\305\202", 2},
//      {"\305\203", "\305\204", 2},
//      {"\305\205", "\305\206", 2},
//      {"\305\207", "\305\210", 2},
//      {"\305\212", "\305\213", 2},
//      {"\305\214", "\305\215", 2},
//      {"\305\216", "\305\217", 2},
//      {"\305\220", "\305\221", 2},
//      {"\305\222", "\305\223", 2},
//      {"\305\224", "\305\225", 2},
//      {"\305\226", "\305\227", 2},
//      {"\305\230", "\305\231", 2},
//      {"\305\232", "\305\233", 2},
//      {"\305\234", "\305\235", 2},
//      {"\305\236", "\305\237", 2},
//      {"\305\240", "\305\241", 2},
//      {"\305\242", "\305\243", 2},
//      {"\305\244", "\305\245", 2},
//      {"\305\246", "\305\247", 2},
//      {"\305\250", "\305\251", 2},
//      {"\305\252", "\305\253", 2},
//      {"\305\254", "\305\255", 2},
//      {"\305\256", "\305\257", 2},
//      {"\305\260", "\305\261", 2},
//      {"\305\262", "\305\263", 2},
//      {"\305\264", "\305\265", 2},
//      {"\305\266", "\305\267", 2},
//      {"\305\271", "\305\272", 2},
//      {"\305\273", "\305\274", 2},
//      {"\305\275", "\305\276", 2},
//      {"\123", "\305\277", 1},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Lower2UpperTbl23[] = {
//      {"\306\202", "\306\203", 2},
//      {"\306\204", "\306\205", 2},
//      {"\306\207", "\306\210", 2},
//      {"\306\213", "\306\214", 2},
//      {"\306\221", "\306\222", 2},
//      {"\306\230", "\306\231", 2},
//      {"\306\240", "\306\241", 2},
//      {"\306\242", "\306\243", 2},
//      {"\306\244", "\306\245", 2},
//      {"\306\247", "\306\250", 2},
//      {"\306\254", "\306\255", 2},
//      {"\306\257", "\306\260", 2},
//      {"\306\263", "\306\264", 2},
//      {"\306\265", "\306\266", 2},
//      {"\306\270", "\306\271", 2},
//      {"\306\274", "\306\275", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Lower2UpperTbl24[] = {
//      {"\307\204", "\307\206", 2},
//      {"\307\207", "\307\211", 2},
//      {"\307\212", "\307\214", 2},
//      {"\307\215", "\307\216", 2},
//      {"\307\217", "\307\220", 2},
//      {"\307\221", "\307\222", 2},
//      {"\307\223", "\307\224", 2},
//      {"\307\225", "\307\226", 2},
//      {"\307\227", "\307\230", 2},
//      {"\307\231", "\307\232", 2},
//      {"\307\233", "\307\234", 2},
//      {"\307\236", "\307\237", 2},
//      {"\307\240", "\307\241", 2},
//      {"\307\242", "\307\243", 2},
//      {"\307\244", "\307\245", 2},
//      {"\307\246", "\307\247", 2},
//      {"\307\250", "\307\251", 2},
//      {"\307\252", "\307\253", 2},
//      {"\307\254", "\307\255", 2},
//      {"\307\256", "\307\257", 2},
//      {"\307\261", "\307\263", 2},
//      {"\307\264", "\307\265", 2},
//      {"\307\272", "\307\273", 2},
//      {"\307\274", "\307\275", 2},
//      {"\307\276", "\307\277", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Lower2UpperTbl25[] = {
//      {"\310\200", "\310\201", 2},
//      {"\310\202", "\310\203", 2},
//      {"\310\204", "\310\205", 2},
//      {"\310\206", "\310\207", 2},
//      {"\310\210", "\310\211", 2},
//      {"\310\212", "\310\213", 2},
//      {"\310\214", "\310\215", 2},
//      {"\310\216", "\310\217", 2},
//      {"\310\220", "\310\221", 2},
//      {"\310\222", "\310\223", 2},
//      {"\310\224", "\310\225", 2},
//      {"\310\226", "\310\227", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Lower2UpperTbl26[] = {
//      {"\306\201", "\311\223", 2},
//      {"\306\206", "\311\224", 2},
//      {"\306\211", "\311\226", 2},
//      {"\306\212", "\311\227", 2},
//      {"\306\216", "\311\230", 2},
//      {"\306\217", "\311\231", 2},
//      {"\306\220", "\311\233", 2},
//      {"\306\223", "\311\240", 2},
//      {"\306\224", "\311\243", 2},
//      {"\306\227", "\311\250", 2},
//      {"\306\226", "\311\251", 2},
//      {"\306\234", "\311\257", 2},
//      {"\306\235", "\311\262", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Lower2UpperTbl27[] = {
//      {"\306\251", "\312\203", 2},
//      {"\306\256", "\312\210", 2},
//      {"\306\261", "\312\212", 2},
//      {"\306\262", "\312\213", 2},
//      {"\306\267", "\312\222", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Lower2UpperTbl28[] = {
//      {"\316\206", "\316\254", 2},
//      {"\316\210", "\316\255", 2},
//      {"\316\211", "\316\256", 2},
//      {"\316\212", "\316\257", 2},
//      {"\316\221", "\316\261", 2},
//      {"\316\222", "\316\262", 2},
//      {"\316\223", "\316\263", 2},
//      {"\316\224", "\316\264", 2},
//      {"\316\225", "\316\265", 2},
//      {"\316\226", "\316\266", 2},
//      {"\316\227", "\316\267", 2},
//      {"\316\230", "\316\270", 2},
//      {"\316\231", "\316\271", 2},
//      {"\316\232", "\316\272", 2},
//      {"\316\233", "\316\273", 2},
//      {"\316\234", "\316\274", 2},
//      {"\316\235", "\316\275", 2},
//      {"\316\236", "\316\276", 2},
//      {"\316\237", "\316\277", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Lower2UpperTbl29[] = {
//      {"\316\240", "\317\200", 2},
//      {"\316\241", "\317\201", 2},
//      {"\316\243", "\317\202", 2},
//      {"\316\243", "\317\203", 2},
//      {"\316\244", "\317\204", 2},
//      {"\316\245", "\317\205", 2},
//      {"\316\246", "\317\206", 2},
//      {"\316\247", "\317\207", 2},
//      {"\316\250", "\317\210", 2},
//      {"\316\251", "\317\211", 2},
//      {"\316\252", "\317\212", 2},
//      {"\316\253", "\317\213", 2},
//      {"\316\214", "\317\214", 2},
//      {"\316\216", "\317\215", 2},
//      {"\316\217", "\317\216", 2},
//      {"\316\222", "\317\220", 2},
//      {"\316\230", "\317\221", 2},
//      {"\316\246", "\317\225", 2},
//      {"\316\240", "\317\226", 2},
//      {"\317\242", "\317\243", 2},
//      {"\317\244", "\317\245", 2},
//      {"\317\246", "\317\247", 2},
//      {"\317\250", "\317\251", 2},
//      {"\317\252", "\317\253", 2},
//      {"\317\254", "\317\255", 2},
//      {"\317\256", "\317\257", 2},
//      {"\316\232", "\317\260", 2},
//      {"\316\241", "\317\261", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Lower2UpperTbl2a[] = {
//      {"\320\220", "\320\260", 2},
//      {"\320\221", "\320\261", 2},
//      {"\320\222", "\320\262", 2},
//      {"\320\223", "\320\263", 2},
//      {"\320\224", "\320\264", 2},
//      {"\320\225", "\320\265", 2},
//      {"\320\226", "\320\266", 2},
//      {"\320\227", "\320\267", 2},
//      {"\320\230", "\320\270", 2},
//      {"\320\231", "\320\271", 2},
//      {"\320\232", "\320\272", 2},
//      {"\320\233", "\320\273", 2},
//      {"\320\234", "\320\274", 2},
//      {"\320\235", "\320\275", 2},
//      {"\320\236", "\320\276", 2},
//      {"\320\237", "\320\277", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Lower2UpperTbl2b[] = {
//      {"\320\240", "\321\200", 2},
//      {"\320\241", "\321\201", 2},
//      {"\320\242", "\321\202", 2},
//      {"\320\243", "\321\203", 2},
//      {"\320\244", "\321\204", 2},
//      {"\320\245", "\321\205", 2},
//      {"\320\246", "\321\206", 2},
//      {"\320\247", "\321\207", 2},
//      {"\320\250", "\321\210", 2},
//      {"\320\251", "\321\211", 2},
//      {"\320\252", "\321\212", 2},
//      {"\320\253", "\321\213", 2},
//      {"\320\254", "\321\214", 2},
//      {"\320\255", "\321\215", 2},
//      {"\320\256", "\321\216", 2},
//      {"\320\257", "\321\217", 2},
//      {"\320\201", "\321\221", 2},
//      {"\320\202", "\321\222", 2},
//      {"\320\203", "\321\223", 2},
//      {"\320\204", "\321\224", 2},
//      {"\320\205", "\321\225", 2},
//      {"\320\206", "\321\226", 2},
//      {"\320\207", "\321\227", 2},
//      {"\320\210", "\321\230", 2},
//      {"\320\211", "\321\231", 2},
//      {"\320\212", "\321\232", 2},
//      {"\320\213", "\321\233", 2},
//      {"\320\214", "\321\234", 2},
//      {"\320\216", "\321\236", 2},
//      {"\320\217", "\321\237", 2},
//      {"\321\240", "\321\241", 2},
//      {"\321\242", "\321\243", 2},
//      {"\321\244", "\321\245", 2},
//      {"\321\246", "\321\247", 2},
//      {"\321\250", "\321\251", 2},
//      {"\321\252", "\321\253", 2},
//      {"\321\254", "\321\255", 2},
//      {"\321\256", "\321\257", 2},
//      {"\321\260", "\321\261", 2},
//      {"\321\262", "\321\263", 2},
//      {"\321\264", "\321\265", 2},
//      {"\321\266", "\321\267", 2},
//      {"\321\270", "\321\271", 2},
//      {"\321\272", "\321\273", 2},
//      {"\321\274", "\321\275", 2},
//      {"\321\276", "\321\277", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Lower2UpperTbl2c[] = {
//      {"\322\200", "\322\201", 2},
//      {"\322\220", "\322\221", 2},
//      {"\322\222", "\322\223", 2},
//      {"\322\224", "\322\225", 2},
//      {"\322\226", "\322\227", 2},
//      {"\322\230", "\322\231", 2},
//      {"\322\232", "\322\233", 2},
//      {"\322\234", "\322\235", 2},
//      {"\322\236", "\322\237", 2},
//      {"\322\240", "\322\241", 2},
//      {"\322\242", "\322\243", 2},
//      {"\322\244", "\322\245", 2},
//      {"\322\246", "\322\247", 2},
//      {"\322\250", "\322\251", 2},
//      {"\322\252", "\322\253", 2},
//      {"\322\254", "\322\255", 2},
//      {"\322\256", "\322\257", 2},
//      {"\322\260", "\322\261", 2},
//      {"\322\262", "\322\263", 2},
//      {"\322\264", "\322\265", 2},
//      {"\322\266", "\322\267", 2},
//      {"\322\270", "\322\271", 2},
//      {"\322\272", "\322\273", 2},
//      {"\322\274", "\322\275", 2},
//      {"\322\276", "\322\277", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Lower2UpperTbl2d[] = {
//      {"\323\201", "\323\202", 2},
//      {"\323\203", "\323\204", 2},
//      {"\323\207", "\323\210", 2},
//      {"\323\213", "\323\214", 2},
//      {"\323\220", "\323\221", 2},
//      {"\323\222", "\323\223", 2},
//      {"\323\224", "\323\225", 2},
//      {"\323\226", "\323\227", 2},
//      {"\323\230", "\323\231", 2},
//      {"\323\232", "\323\233", 2},
//      {"\323\234", "\323\235", 2},
//      {"\323\236", "\323\237", 2},
//      {"\323\240", "\323\241", 2},
//      {"\323\242", "\323\243", 2},
//      {"\323\244", "\323\245", 2},
//      {"\323\246", "\323\247", 2},
//      {"\323\250", "\323\251", 2},
//      {"\323\252", "\323\253", 2},
//      {"\323\256", "\323\257", 2},
//      {"\323\260", "\323\261", 2},
//      {"\323\262", "\323\263", 2},
//      {"\323\264", "\323\265", 2},
//      {"\323\270", "\323\271", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Lower2UpperTbl2e[] = {
//      {"\324\261", "\325\241", 2},
//      {"\324\262", "\325\242", 2},
//      {"\324\263", "\325\243", 2},
//      {"\324\264", "\325\244", 2},
//      {"\324\265", "\325\245", 2},
//      {"\324\266", "\325\246", 2},
//      {"\324\267", "\325\247", 2},
//      {"\324\270", "\325\250", 2},
//      {"\324\271", "\325\251", 2},
//      {"\324\272", "\325\252", 2},
//      {"\324\273", "\325\253", 2},
//      {"\324\274", "\325\254", 2},
//      {"\324\275", "\325\255", 2},
//      {"\324\276", "\325\256", 2},
//      {"\324\277", "\325\257", 2},
//      {"\325\200", "\325\260", 2},
//      {"\325\201", "\325\261", 2},
//      {"\325\202", "\325\262", 2},
//      {"\325\203", "\325\263", 2},
//      {"\325\204", "\325\264", 2},
//      {"\325\205", "\325\265", 2},
//      {"\325\206", "\325\266", 2},
//      {"\325\207", "\325\267", 2},
//      {"\325\210", "\325\270", 2},
//      {"\325\211", "\325\271", 2},
//      {"\325\212", "\325\272", 2},
//      {"\325\213", "\325\273", 2},
//      {"\325\214", "\325\274", 2},
//      {"\325\215", "\325\275", 2},
//      {"\325\216", "\325\276", 2},
//      {"\325\217", "\325\277", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Lower2UpperTbl2f[] = {
//      {"\325\220", "\326\200", 2},
//      {"\325\221", "\326\201", 2},
//      {"\325\222", "\326\202", 2},
//      {"\325\223", "\326\203", 2},
//      {"\325\224", "\326\204", 2},
//      {"\325\225", "\326\205", 2},
//      {"\325\226", "\326\206", 2},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Lower2UpperTbl30[] = {
//      {"\341\202\240", "\341\203\220", 3},
//      {"\341\202\241", "\341\203\221", 3},
//      {"\341\202\242", "\341\203\222", 3},
//      {"\341\202\243", "\341\203\223", 3},
//      {"\341\202\244", "\341\203\224", 3},
//      {"\341\202\245", "\341\203\225", 3},
//      {"\341\202\246", "\341\203\226", 3},
//      {"\341\202\247", "\341\203\227", 3},
//      {"\341\202\250", "\341\203\230", 3},
//      {"\341\202\251", "\341\203\231", 3},
//      {"\341\202\252", "\341\203\232", 3},
//      {"\341\202\253", "\341\203\233", 3},
//      {"\341\202\254", "\341\203\234", 3},
//      {"\341\202\255", "\341\203\235", 3},
//      {"\341\202\256", "\341\203\236", 3},
//      {"\341\202\257", "\341\203\237", 3},
//      {"\341\202\260", "\341\203\240", 3},
//      {"\341\202\261", "\341\203\241", 3},
//      {"\341\202\262", "\341\203\242", 3},
//      {"\341\202\263", "\341\203\243", 3},
//      {"\341\202\264", "\341\203\244", 3},
//      {"\341\202\265", "\341\203\245", 3},
//      {"\341\202\266", "\341\203\246", 3},
//      {"\341\202\267", "\341\203\247", 3},
//      {"\341\202\270", "\341\203\250", 3},
//      {"\341\202\271", "\341\203\251", 3},
//      {"\341\202\272", "\341\203\252", 3},
//      {"\341\202\273", "\341\203\253", 3},
//      {"\341\202\274", "\341\203\254", 3},
//      {"\341\202\275", "\341\203\255", 3},
//      {"\341\202\276", "\341\203\256", 3},
//      {"\341\202\277", "\341\203\257", 3},
//      {"\341\203\200", "\341\203\260", 3},
//      {"\341\203\201", "\341\203\261", 3},
//      {"\341\203\202", "\341\203\262", 3},
//      {"\341\203\203", "\341\203\263", 3},
//      {"\341\203\204", "\341\203\264", 3},
//      {"\341\203\205", "\341\203\265", 3},
//      {"\341\270\200", "\341\270\201", 3},
//      {"\341\270\202", "\341\270\203", 3},
//      {"\341\270\204", "\341\270\205", 3},
//      {"\341\270\206", "\341\270\207", 3},
//      {"\341\270\210", "\341\270\211", 3},
//      {"\341\270\212", "\341\270\213", 3},
//      {"\341\270\214", "\341\270\215", 3},
//      {"\341\270\216", "\341\270\217", 3},
//      {"\341\270\220", "\341\270\221", 3},
//      {"\341\270\222", "\341\270\223", 3},
//      {"\341\270\224", "\341\270\225", 3},
//      {"\341\270\226", "\341\270\227", 3},
//      {"\341\270\230", "\341\270\231", 3},
//      {"\341\270\232", "\341\270\233", 3},
//      {"\341\270\234", "\341\270\235", 3},
//      {"\341\270\236", "\341\270\237", 3},
//      {"\341\270\240", "\341\270\241", 3},
//      {"\341\270\242", "\341\270\243", 3},
//      {"\341\270\244", "\341\270\245", 3},
//      {"\341\270\246", "\341\270\247", 3},
//      {"\341\270\250", "\341\270\251", 3},
//      {"\341\270\252", "\341\270\253", 3},
//      {"\341\270\254", "\341\270\255", 3},
//      {"\341\270\256", "\341\270\257", 3},
//      {"\341\270\260", "\341\270\261", 3},
//      {"\341\270\262", "\341\270\263", 3},
//      {"\341\270\264", "\341\270\265", 3},
//      {"\341\270\266", "\341\270\267", 3},
//      {"\341\270\270", "\341\270\271", 3},
//      {"\341\270\272", "\341\270\273", 3},
//      {"\341\270\274", "\341\270\275", 3},
//      {"\341\270\276", "\341\270\277", 3},
//      {"\341\271\200", "\341\271\201", 3},
//      {"\341\271\202", "\341\271\203", 3},
//      {"\341\271\204", "\341\271\205", 3},
//      {"\341\271\206", "\341\271\207", 3},
//      {"\341\271\210", "\341\271\211", 3},
//      {"\341\271\212", "\341\271\213", 3},
//      {"\341\271\214", "\341\271\215", 3},
//      {"\341\271\216", "\341\271\217", 3},
//      {"\341\271\220", "\341\271\221", 3},
//      {"\341\271\222", "\341\271\223", 3},
//      {"\341\271\224", "\341\271\225", 3},
//      {"\341\271\226", "\341\271\227", 3},
//      {"\341\271\230", "\341\271\231", 3},
//      {"\341\271\232", "\341\271\233", 3},
//      {"\341\271\234", "\341\271\235", 3},
//      {"\341\271\236", "\341\271\237", 3},
//      {"\341\271\240", "\341\271\241", 3},
//      {"\341\271\242", "\341\271\243", 3},
//      {"\341\271\244", "\341\271\245", 3},
//      {"\341\271\246", "\341\271\247", 3},
//      {"\341\271\250", "\341\271\251", 3},
//      {"\341\271\252", "\341\271\253", 3},
//      {"\341\271\254", "\341\271\255", 3},
//      {"\341\271\256", "\341\271\257", 3},
//      {"\341\271\260", "\341\271\261", 3},
//      {"\341\271\262", "\341\271\263", 3},
//      {"\341\271\264", "\341\271\265", 3},
//      {"\341\271\266", "\341\271\267", 3},
//      {"\341\271\270", "\341\271\271", 3},
//      {"\341\271\272", "\341\271\273", 3},
//      {"\341\271\274", "\341\271\275", 3},
//      {"\341\271\276", "\341\271\277", 3},
//      {"\341\272\200", "\341\272\201", 3},
//      {"\341\272\202", "\341\272\203", 3},
//      {"\341\272\204", "\341\272\205", 3},
//      {"\341\272\206", "\341\272\207", 3},
//      {"\341\272\210", "\341\272\211", 3},
//      {"\341\272\212", "\341\272\213", 3},
//      {"\341\272\214", "\341\272\215", 3},
//      {"\341\272\216", "\341\272\217", 3},
//      {"\341\272\220", "\341\272\221", 3},
//      {"\341\272\222", "\341\272\223", 3},
//      {"\341\272\224", "\341\272\225", 3},
//      {"\341\272\240", "\341\272\241", 3},
//      {"\341\272\242", "\341\272\243", 3},
//      {"\341\272\244", "\341\272\245", 3},
//      {"\341\272\246", "\341\272\247", 3},
//      {"\341\272\250", "\341\272\251", 3},
//      {"\341\272\252", "\341\272\253", 3},
//      {"\341\272\254", "\341\272\255", 3},
//      {"\341\272\256", "\341\272\257", 3},
//      {"\341\272\260", "\341\272\261", 3},
//      {"\341\272\262", "\341\272\263", 3},
//      {"\341\272\264", "\341\272\265", 3},
//      {"\341\272\266", "\341\272\267", 3},
//      {"\341\272\270", "\341\272\271", 3},
//      {"\341\272\272", "\341\272\273", 3},
//      {"\341\272\274", "\341\272\275", 3},
//      {"\341\272\276", "\341\272\277", 3},
//      {"\341\273\200", "\341\273\201", 3},
//      {"\341\273\202", "\341\273\203", 3},
//      {"\341\273\204", "\341\273\205", 3},
//      {"\341\273\206", "\341\273\207", 3},
//      {"\341\273\210", "\341\273\211", 3},
//      {"\341\273\212", "\341\273\213", 3},
//      {"\341\273\214", "\341\273\215", 3},
//      {"\341\273\216", "\341\273\217", 3},
//      {"\341\273\220", "\341\273\221", 3},
//      {"\341\273\222", "\341\273\223", 3},
//      {"\341\273\224", "\341\273\225", 3},
//      {"\341\273\226", "\341\273\227", 3},
//      {"\341\273\230", "\341\273\231", 3},
//      {"\341\273\232", "\341\273\233", 3},
//      {"\341\273\234", "\341\273\235", 3},
//      {"\341\273\236", "\341\273\237", 3},
//      {"\341\273\240", "\341\273\241", 3},
//      {"\341\273\242", "\341\273\243", 3},
//      {"\341\273\244", "\341\273\245", 3},
//      {"\341\273\246", "\341\273\247", 3},
//      {"\341\273\250", "\341\273\251", 3},
//      {"\341\273\252", "\341\273\253", 3},
//      {"\341\273\254", "\341\273\255", 3},
//      {"\341\273\256", "\341\273\257", 3},
//      {"\341\273\260", "\341\273\261", 3},
//      {"\341\273\262", "\341\273\263", 3},
//      {"\341\273\264", "\341\273\265", 3},
//      {"\341\273\266", "\341\273\267", 3},
//      {"\341\273\270", "\341\273\271", 3},
//      {"\341\274\210", "\341\274\200", 3},
//      {"\341\274\211", "\341\274\201", 3},
//      {"\341\274\212", "\341\274\202", 3},
//      {"\341\274\213", "\341\274\203", 3},
//      {"\341\274\214", "\341\274\204", 3},
//      {"\341\274\215", "\341\274\205", 3},
//      {"\341\274\216", "\341\274\206", 3},
//      {"\341\274\217", "\341\274\207", 3},
//      {"\341\274\230", "\341\274\220", 3},
//      {"\341\274\231", "\341\274\221", 3},
//      {"\341\274\232", "\341\274\222", 3},
//      {"\341\274\233", "\341\274\223", 3},
//      {"\341\274\234", "\341\274\224", 3},
//      {"\341\274\235", "\341\274\225", 3},
//      {"\341\274\250", "\341\274\240", 3},
//      {"\341\274\251", "\341\274\241", 3},
//      {"\341\274\252", "\341\274\242", 3},
//      {"\341\274\253", "\341\274\243", 3},
//      {"\341\274\254", "\341\274\244", 3},
//      {"\341\274\255", "\341\274\245", 3},
//      {"\341\274\256", "\341\274\246", 3},
//      {"\341\274\257", "\341\274\247", 3},
//      {"\341\274\270", "\341\274\260", 3},
//      {"\341\274\271", "\341\274\261", 3},
//      {"\341\274\272", "\341\274\262", 3},
//      {"\341\274\273", "\341\274\263", 3},
//      {"\341\274\274", "\341\274\264", 3},
//      {"\341\274\275", "\341\274\265", 3},
//      {"\341\274\276", "\341\274\266", 3},
//      {"\341\274\277", "\341\274\267", 3},
//      {"\341\275\210", "\341\275\200", 3},
//      {"\341\275\211", "\341\275\201", 3},
//      {"\341\275\212", "\341\275\202", 3},
//      {"\341\275\213", "\341\275\203", 3},
//      {"\341\275\214", "\341\275\204", 3},
//      {"\341\275\215", "\341\275\205", 3},
//      {"\341\275\231", "\341\275\221", 3},
//      {"\341\275\233", "\341\275\223", 3},
//      {"\341\275\235", "\341\275\225", 3},
//      {"\341\275\237", "\341\275\227", 3},
//      {"\341\275\250", "\341\275\240", 3},
//      {"\341\275\251", "\341\275\241", 3},
//      {"\341\275\252", "\341\275\242", 3},
//      {"\341\275\253", "\341\275\243", 3},
//      {"\341\275\254", "\341\275\244", 3},
//      {"\341\275\255", "\341\275\245", 3},
//      {"\341\275\256", "\341\275\246", 3},
//      {"\341\275\257", "\341\275\247", 3},
//      {"\341\276\272", "\341\275\260", 3},
//      {"\341\276\273", "\341\275\261", 3},
//      {"\341\277\210", "\341\275\262", 3},
//      {"\341\277\211", "\341\275\263", 3},
//      {"\341\277\212", "\341\275\264", 3},
//      {"\341\277\213", "\341\275\265", 3},
//      {"\341\277\232", "\341\275\266", 3},
//      {"\341\277\233", "\341\275\267", 3},
//      {"\341\277\270", "\341\275\270", 3},
//      {"\341\277\271", "\341\275\271", 3},
//      {"\341\277\252", "\341\275\272", 3},
//      {"\341\277\253", "\341\275\273", 3},
//      {"\341\277\272", "\341\275\274", 3},
//      {"\341\277\273", "\341\275\275", 3},
//      {"\341\276\210", "\341\276\200", 3},
//      {"\341\276\211", "\341\276\201", 3},
//      {"\341\276\212", "\341\276\202", 3},
//      {"\341\276\213", "\341\276\203", 3},
//      {"\341\276\214", "\341\276\204", 3},
//      {"\341\276\215", "\341\276\205", 3},
//      {"\341\276\216", "\341\276\206", 3},
//      {"\341\276\217", "\341\276\207", 3},
//      {"\341\276\230", "\341\276\220", 3},
//      {"\341\276\231", "\341\276\221", 3},
//      {"\341\276\232", "\341\276\222", 3},
//      {"\341\276\233", "\341\276\223", 3},
//      {"\341\276\234", "\341\276\224", 3},
//      {"\341\276\235", "\341\276\225", 3},
//      {"\341\276\236", "\341\276\226", 3},
//      {"\341\276\237", "\341\276\227", 3},
//      {"\341\276\250", "\341\276\240", 3},
//      {"\341\276\251", "\341\276\241", 3},
//      {"\341\276\252", "\341\276\242", 3},
//      {"\341\276\253", "\341\276\243", 3},
//      {"\341\276\254", "\341\276\244", 3},
//      {"\341\276\255", "\341\276\245", 3},
//      {"\341\276\256", "\341\276\246", 3},
//      {"\341\276\257", "\341\276\247", 3},
//      {"\341\276\270", "\341\276\260", 3},
//      {"\341\276\271", "\341\276\261", 3},
//      {"\341\276\274", "\341\276\263", 3},
//      {"\341\277\214", "\341\277\203", 3},
//      {"\341\277\230", "\341\277\220", 3},
//      {"\341\277\231", "\341\277\221", 3},
//      {"\341\277\250", "\341\277\240", 3},
//      {"\341\277\251", "\341\277\241", 3},
//      {"\341\277\254", "\341\277\245", 3},
//      {"\341\277\274", "\341\277\263", 3},
//      {NULL, NULL, 0}
//  };

//  UpperLowerTbl_t Lower2UpperTbl31[] = {
//      {"\357\274\241", "\357\275\201", 3},
//      {"\357\274\242", "\357\275\202", 3},
//      {"\357\274\243", "\357\275\203", 3},
//      {"\357\274\244", "\357\275\204", 3},
//      {"\357\274\245", "\357\275\205", 3},
//      {"\357\274\246", "\357\275\206", 3},
//      {"\357\274\247", "\357\275\207", 3},
//      {"\357\274\250", "\357\275\210", 3},
//      {"\357\274\251", "\357\275\211", 3},
//      {"\357\274\252", "\357\275\212", 3},
//      {"\357\274\253", "\357\275\213", 3},
//      {"\357\274\254", "\357\275\214", 3},
//      {"\357\274\255", "\357\275\215", 3},
//      {"\357\274\256", "\357\275\216", 3},
//      {"\357\274\257", "\357\275\217", 3},
//      {"\357\274\260", "\357\275\220", 3},
//      {"\357\274\261", "\357\275\221", 3},
//      {"\357\274\262", "\357\275\222", 3},
//      {"\357\274\263", "\357\275\223", 3},
//      {"\357\274\264", "\357\275\224", 3},
//      {"\357\274\265", "\357\275\225", 3},
//      {"\357\274\266", "\357\275\226", 3},
//      {"\357\274\267", "\357\275\227", 3},
//      {"\357\274\270", "\357\275\230", 3},
//      {"\357\274\271", "\357\275\231", 3},
//      {"\357\274\272", "\357\275\232", 3},
//      {NULL, NULL, 0}
//      /* upper, lower */
//  };

//  UpperLowerTbl_t *Lower2UpperTbl2[] = {
//      Lower2UpperTbl20,	/* \303 */
//      Lower2UpperTbl21,	/* \304 */
//      Lower2UpperTbl22,	/* \305 */
//      Lower2UpperTbl23,	/* \306 */
//      Lower2UpperTbl24,	/* \307 */
//      Lower2UpperTbl25,	/* \310 */
//      Lower2UpperTbl26,	/* \311 */
//      Lower2UpperTbl27,	/* \312 */
//      NULL,		/* \313 */
//      NULL,		/* \314 */
//      NULL,		/* \315 */
//      Lower2UpperTbl28,	/* \316 */
//      Lower2UpperTbl29,	/* \317 */
//      Lower2UpperTbl2a,	/* \320 */
//      Lower2UpperTbl2b,	/* \321 */
//      Lower2UpperTbl2c,	/* \322 */
//      Lower2UpperTbl2d,	/* \323 */
//      NULL,		/* \324 */
//      Lower2UpperTbl2e,	/* \325 */
//      Lower2UpperTbl2f	/* \326 */
//  };

//  UpperLowerTbl_t *Lower2UpperTbl3[] = {
//      Lower2UpperTbl30,	/* \341 */
//      NULL,		/* \342 */
//      NULL,		/* \343 */
//      NULL,		/* \344 */
//      NULL,		/* \345 */
//      NULL,		/* \346 */
//      NULL,		/* \347 */
//      NULL,		/* \350 */
//      NULL,		/* \351 */
//      NULL,		/* \352 */
//      NULL,		/* \353 */
//      NULL,		/* \354 */
//      NULL,		/* \355 */
//      NULL,		/* \356 */
//      Lower2UpperTbl31	/* \357 */
//  };

//  #define LU2S (unsigned char)'\303'
//  #define LU2E (unsigned char)'\326'
//  #define LU3S (unsigned char)'\341'
//  #define LU3E (unsigned char)'\357'

//  /*
//   * ldap_utf8StrToUpper: translate lower-case string to upper-case
//   * 
//   *                input: a null terminated UTF-8 string
//   *               output: a null terminated UTF-8 string which characters are
//   *                       converted to upper-case; characters which are not
//   *                       lower-case are copied as is.  If it's not considered
//   *                       a UTF-8 string, NULL is returned.
//   *                   
//   * Notes: This function takes a string (made of multiple UTF-8 characters)
//   *        for the input (not one character as in "toupper").
//   *        Output string is allocated in this function, which needs to be
//   *        released when it's not needed any more.
//   */
//  unsigned char *
//  ldap_UTF8STRTOUPPER(char *s)
//  {
//      return ldap_utf8StrToUpper((unsigned char *)s);
//  }

//  unsigned char *
//  ldap_utf8StrToUpper(unsigned char *s)
//  {
//    UpperLowerTbl_t *ultp;
//    unsigned char *p, *np, *tail;
//    unsigned char *up, *uphead;
//    int len, sz;
  
//    if (s == NULL || *s == '\0') {
//      return s;
//    }
//    len = strlen((char *)s);
//    tail = s + len;
//    uphead = up = (unsigned char *)malloc(len + 1);
//    p = s;
//    while ((np = (unsigned char *)ldap_utf8next((char *)p)) <= tail) {
//      switch(sz = np - p) {
//      case 1:	/* ASCII */
//        sprintf((char *)up, "%c", toupper(*p));
//        break;
//      case 2:	/* 2 bytes */
//        if (*p < LU2S || *p > LU2E) {	/* out of range */
//  	memcpy(up, p, sz);
//  	break;
//        }
//        for (ultp = Lower2UpperTbl2[*p - LU2S];
//  	   ultp && ultp->lower && memcmp(p, ultp->lower, sz);
//  	   ultp++)
//  	;
//        if (!ultp) {		/* out of range */
//  	memcpy(up, p, sz);
//        } else if (ultp->lower) {        /* matched */
//  	memcpy(up, ultp->upper, ultp->tsz);
//  	sz = ultp->tsz;
//        } else {
//  	memcpy(up, p, sz);
//        }
//        break;
//          case 3:	/* 3 bytes */
//  	  if (*p != LU3S && *p != LU3E) {	/* out of range */
//  	    memcpy(up, p, sz);
//  	    break;
//  	  }
//  	  for (ultp = Lower2UpperTbl3[*p - LU3S];
//  	       ultp && ultp->lower && memcmp(p, ultp->lower, sz);
//  	       ultp++)
//  	    ;
//  	  if (!ultp) {	/* out of range */
//  	    memcpy(up, p, sz);
//  	  } else if (ultp->lower) {        /* matched */
//  	    memcpy(up, ultp->upper, sz);
//  	  } else {
//  	    memcpy(up, p, sz);
//  	  }
//  	  break;
//      case 4:
//        memcpy(up, p, sz);
//        break;
//      default:    /* not UTF-8 */
//        free((void *)uphead);
//              return NULL;
//      }
//      up += sz;
//      p = np;
//      if (p == tail) {
//        break;
//      }
//    }
//    *up = '\0';
//    return uphead;
//  }

//  /*
//   * ldap_utf8ToUpper: translate lower-case character to upper-case
//   * 
//   *             input: a UTF-8 character (s)
//   *            output: a UTF-8 character which is converted to upper-case (d)
//   *                    length (in bytes) of input character (ssz) and
//   *                    output character (dsz)
//   *                   
//   * Notes: This function takes a UTF-8 character (could be multiple bytes)
//   *        for the input.  Memory for the output character is NOT allocated
//   *        in this function, caller should have allocated it (d).
//   *        "memmove" is used since (s) and (d) are overlapped.
//   */
//  void
//  ldap_UTF8TOUPPER(char *s, char *d, int *ssz, int *dsz)
//  {
//    ldap_utf8ToUpper((unsigned char *)s, (unsigned char *)d, ssz, dsz);
//    return;
//  }

//  void
//  ldap_utf8ToUpper(unsigned char *s, unsigned char *d, int *ssz, int *dsz)
//  {
//    UpperLowerTbl_t *ultp;
//    unsigned char *tail;
  
//    if (s == NULL || *s == '\0') {
//      *ssz = *dsz = 0;
//      return;
//    }
//    if (!(*s & 0x80)) {	/* ASCII */
//      *dsz = *ssz = 1;
//      *d = toupper(*s);
//      return;
//    }
//    tail = (unsigned char *)ldap_utf8next((char *)s);
//    *dsz = *ssz = tail - s;
//    switch(*ssz) {
//    case 1:	/* ASCII */
//      *d = toupper(*s);
//      break;
//    case 2:	/* 2 bytes */
//      if (*s < LU2S || *s > LU2E) {	/* out of range */
//        memmove(d, s, *ssz);
//        break;
//      }
//      for (ultp = Lower2UpperTbl2[*s - LU2S];
//  	 ultp && ultp->lower && memcmp(s, ultp->lower, *ssz);
//  	 ultp++)
//        ;
//      if (!ultp) {		        /* out of range */
//        memmove(d, s, *ssz);
//      } else if (ultp->lower) {	/* matched */
//        memmove(d, ultp->upper, ultp->tsz);
//        *dsz = ultp->tsz;
//      } else {
//        memmove(d, s, *ssz);
//      }
//      break;
//    case 3:	/* 3 bytes */
//      if (*s != LU3S && *s != LU3E) {	/* out of range */
//        memmove(d, s, *ssz);
//        break;
//      }
//      for (ultp = Lower2UpperTbl3[*s - LU3S];
//  	 ultp && ultp->lower && memcmp(s, ultp->lower, *ssz);
//  	 ultp++)
//        ;
//      if (!ultp) {			/* out of range */
//        memmove(d, s, *ssz);
//      } else if (ultp->lower) {	/* matched */
//        memmove(d, ultp->upper, *ssz);
//      } else {
//        memmove(d, s, *ssz);
//      }
//      break;
//    }
//    return;
//  }

//  /*
//   * ldap_utf8isLower: tests for a character that is a lower-case letter in
//   *                   UTF-8
//   * 
//   *            input: a UTF-8 character (could be multi-byte)
//   *           output: 1 if the character is a lower-case letter
//   *                   0 if the character is not a lower-case letter
//   */
//  int
//  ldap_UTF8ISLOWER(char *s)
//  {
//    return ldap_utf8isLower((unsigned char *)s);
//  }

//  int
//  ldap_utf8isLower(unsigned char *s)
//  {
//    UpperLowerTbl_t *ultp;
//    unsigned char *next;
//    int sz;
  
//    if (s == NULL || *s == '\0') {
//      return 0;
//    }
//    if (!(*s & 0x80)) {	/* ASCII */
//      return islower(*s);
//    }
//    next = (unsigned char *)ldap_utf8next((char *)s);
//    switch(sz = next - s) {
//    case 1:	/* ASCII */
//          return islower(*s);
//    case 2:
//      if (*s < LU2S || *s > LU2E) {	/* out of range */
//        return 0;
//      }
//      for (ultp = Lower2UpperTbl2[*s - LU2S];
//  	 ultp && ultp->lower && memcmp(s, ultp->lower, sz);
//  	 ultp++)
//        ;
//      if (!ultp) {		/* out of range */
//        return 0;
//      } else if (ultp->lower) {	/* matched */
//        return 1;
//      } else {
//        return 0;
//      }
//    case 3:
//      if (*s < LU3S || *s > LU3E) {	/* out of range */
//        return 0;
//      }
//      for (ultp = Lower2UpperTbl3[*s - LU3S];
//  	 ultp && ultp->lower && memcmp(s, ultp->lower, sz);
//  	 ultp++)
//        ;
//      if (!ultp) {		/* out of range */
//        return 0;
//      } else if (ultp->lower) {	/* matched */
//        return 1;
//      } else {
//        return 0;
//      }
//    default:
//      return 0;
//    }
//  }

//  /*
//   * ldap_utf8casecmp: case-insensitive string compare for UTF-8 strings
//   * 
//   *            input: two UTF-8 strings (s0, s1) to be compared
//   *           output: positive number, if s0 is after s1
//   *                   0, if the two strings are identical ignoring the case
//   *                   negative number, if s1 is after s0
//   *
//   * Rules: If both UTF-8 strings are NULL or 0-length, 0 is returned.
//   *        If one of the strings is NULL or 0-length, the NULL/0-length
//   *            string is smaller.
//   *        If one or both of the strings are not UTF-8, system provided
//   *            strcasecmp is used.
//   *        If one of the two strings contains no 8-bit characters,
//   *            strcasecmp is used.
//   *        The strings are compared after converted to lower-case UTF-8.
//   *        Each character is compared from the beginning.
//   *            Evaluation goes in this order:
//   *            If the length of one character is shorter then the other,
//   *                the difference of the two lengths is returned.
//   *            If the length of the corresponsing characters is same,
//   *                each byte in the characters is compared.
//   *                If there's a difference between two bytes,
//   *                the diff is returned.
//   *            If one string is shorter then the other, the diff is returned.
//   *
//   * Notes: Don't use this function for collation
//   *        1) there's no notion of locale in this function.
//   *        2) it's UTF-8 code order, which is different from the locale
//   *           based collation.
//   */
//  int
//  ldap_UTF8CASECMP(char *s0, char *s1)
//  {
//      return ldap_utf8casecmp((unsigned char *)s0, (unsigned char *)s1);
//  }

//  int
//  ldap_utf8casecmp(const unsigned char *s0, const unsigned char *s1)
//  {
//      unsigned char *d0, *d1;	/* store lower-case strings */
//      unsigned char *p0, *p1;	/* current UTF-8 char */
//      unsigned char *n0, *n1;	/* next UTF-8 char */
//      unsigned char *t0, *t1;	/* tail of the strings */
//      unsigned char *x0, *x1;	/* current byte in a char */
//      int i0, i1;			/* length of characters */
//      int l0, l1;			/* length of leftover */
//      int rval;
//      int has8_s0;
//      int has8_s1;

//      d0 = d1 = NULL;
//      if (s0 == NULL || *s0 == '\0') {
//  	if (s1 == NULL || *s1 == '\0') {
//  	    rval = 0;
//  	} else {
//  	    rval = -1;	/* regardless s1, s0 < s1 */
//  	}
//  	goto end;
//      } else if (s1 == NULL || *s1 == '\0') {
//  	rval = 1;	/* regardless s0, s0 > s1 */
//  	goto end;
//      }

//      has8_s0 = ldap_has8thBit(s0);
//      has8_s1 = ldap_has8thBit(s1);
//      if (has8_s0 == has8_s1) { /* both has-8th-bit or both do not */
//          if (has8_s0 == 0) {          /* neither has-8th-bit */
//              rval = strcasecmp((char *)s0, (char *)s1);
//              goto end;
//          }
//      } else {                  /* one has and the other do not */
//          rval = strcasecmp((char *)s0, (char *)s1);
//          goto end;
//      }

//      d0 = ldap_utf8StrToLower(s0);
//      d1 = ldap_utf8StrToLower(s1);
//      if (d0 == NULL || d1 == NULL || /* either is not a UTF-8 string */
//  	(d0 && *d0 == '\0') || (d1 && *d1 == '\0')) {	
//  	rval = strcasecmp((char *)s0, (char *)s1);
//  	goto end;
//      }

//      p0 = d0;
//      p1 = d1;

//      t0 = d0 + strlen((char *)d0);
//      t1 = d1 + strlen((char *)d1);

//      rval = 0;
//      while (1) {
//          n0 = (unsigned char *)ldap_utf8next((char *)p0);
//          n1 = (unsigned char *)ldap_utf8next((char *)p1);
//          if (n0 > t0 || n1 > t1) {
//  	    break;
//  	}

//          i0 = n0 - p0;
//          i1 = n1 - p1;
//  	rval = i0 - i1;
//          if (rval) {         /* length is different */
//              goto end;
//  	}

//          /* i0 == i1: same length */
//          for (x0 = p0, x1 = p1; x0 < n0; x0++, x1++) {
//              rval = *x0 - *x1;
//              if (rval) {
//                  goto end;
//  	    }
//          }

//  	p0 = n0; p1 = n1;	/* goto next */
//      }
//      /* finished scanning the shared part and check the leftover */
//      l0 = t0 - n0;
//      l1 = t1 - n1;
//      rval = l0 - l1;

//  end:
//      if (d0)
//          free((void *)d0);
//      if (d1)
//          free((void *)d1);

//      return rval;
//  }

//  /*
//   * ldap_utf8ncasecmp: case-insensitive string compare (n chars) for UTF-8
//   *                    strings
//   * 
//   *            input: two UTF-8 strings (s0, s1) to be compared
//   *                   number or characters
//   *           output: positive number, if s0 is after s1
//   *                   0, if the two strings are identical ignoring the case
//   *                   negative number, if s1 is after s0
//   *
//   * Rules: Same as ldap_utf8casecmp except the n characters limit.
//   *
//   * Notes: Don't use this function for collation
//   *        1) there's no notion of locale in this function.
//   *        2) it's UTF-8 code order, which is different from the locale
//   *           based collation.
//   *        n characters, NOT n bytes
//   */
//  int
//  ldap_UTF8NCASECMP(char *s0, char *s1, int n)
//  {
//      return ldap_utf8ncasecmp((unsigned char *)s0, (unsigned char *)s1, n);
//  }

//  int
//  ldap_utf8ncasecmp(const unsigned char *s0, const unsigned char *s1, int n)
//  {
//      unsigned char *d0, *d1;	/* store lower-case strings */
//      unsigned char *p0, *p1;	/* current UTF-8 char */
//      unsigned char *n0, *n1;	/* next UTF-8 char */
//      unsigned char *t0, *t1;	/* tail of the strings */
//      unsigned char *x0, *x1;	/* current byte in a char */
//      int i0, i1;			/* length of characters */
//      int l0, l1;			/* length of leftover */
//      int cnt;
//      int rval;
//      int has8_s0;
//      int has8_s1;

//      d0 = d1 = NULL;
//      if (s0 == NULL || *s0 == '\0') {
//  	if (s1 == NULL || *s1 == '\0') {
//  	    rval = 0;
//  	} else {
//  	    rval = -1;	/* regardless s1, s0 < s1 */
//  	}
//  	goto end;
//      } else if (s1 == NULL || *s1 == '\0') {
//  	rval = 1;	/* regardless s0, s0 > s1 */
//  	goto end;
//      }

//      has8_s0 = ldap_has8thBit(s0);
//      has8_s1 = ldap_has8thBit(s1);
//      if (has8_s0 == has8_s1) { /* both has-8th-bit or both do not */
//          if (has8_s0 == 0) {          /* neither has-8th-bit */
//              rval = strncasecmp((char *)s0, (char *)s1, n);
//              goto end;
//          }
//      } else {                  /* one has and the other do not */
//          rval = strncasecmp((char *)s0, (char *)s1, n);
//          goto end;
//      }

//      d0 = ldap_utf8StrToLower(s0);
//      d1 = ldap_utf8StrToLower(s1);

//      if (d0 == NULL || d1 == NULL || /* either is not a UTF-8 string */
//  	(d0 && *d0 == '\0') || (d1 && *d1 == '\0')) {	
//  	rval = strncasecmp((char *)s0, (char *)s1, n);
//  	goto end;
//      }

//      p0 = d0;
//      p1 = d1;

//      t0 = d0 + strlen((char *)d0);
//      t1 = d1 + strlen((char *)d1);

//      rval = 0;
//      cnt = 0;
//      while (1) {
//          n0 = (unsigned char *)ldap_utf8next((char *)p0);
//          n1 = (unsigned char *)ldap_utf8next((char *)p1);
//          if (n0 > t0 || n1 > t1 || cnt == n) {
//  	    break;
//  	}

//          i0 = n0 - p0;
//          i1 = n1 - p1;
//          rval = i0 - i1;
//          if (rval)         /* length is different */
//              goto end;

//          /* i0 == i1: same length */
//          for (x0 = p0, x1 = p1; x0 < n0; x0++, x1++) {
//              rval = *x0 - *x1;
//              if (rval)
//                  goto end;
//          }

//  	p0 = n0; p1 = n1;	/* goto next */
//  	cnt++;
//      }
//      if (cnt == n) 
//  	rval = 0;
//      else {
//          /* finished scanning the shared part and check the leftover */
//          l0 = t0 - n0;
//          l1 = t1 - n1;
//          rval = l0 - l1;
//      }

//  end:
//      if (d0)
//          free((void *)d0);
//      if (d1)
//          free((void *)d1);

//      return rval;
//  }

